diff --git a/hwe/b_dipcenter.php b/hwe/b_dipcenter.php index fb94dd08..564afe03 100644 --- a/hwe/b_dipcenter.php +++ b/hwe/b_dipcenter.php @@ -55,16 +55,19 @@ $nationStor->cacheValues(['notice', 'scout_msg']); <?=UniqueConst::$serverName?>: 내무부 + + @@ -199,7 +202,7 @@ if ($budgetricediff > 0) {
870px x 200px를 넘어서는 내용은 표시되지 않습니다.
- +
diff --git a/hwe/c_dipcenter.php b/hwe/c_dipcenter.php index 66c6efcf..192f2424 100644 --- a/hwe/c_dipcenter.php +++ b/hwe/c_dipcenter.php @@ -7,7 +7,7 @@ include "func.php"; $btn = Util::getPost('btn'); $msg = Util::getPost('msg'); -$scoutmsg = Util::getPost('scoutmsg'); +$scoutmsg = Util::getPost('scoutMsg'); $rate = Util::getPost('rate', 'int'); $bill = Util::getPost('bill', 'int'); $secretlimit = Util::getPost('secretlimit', 'int'); @@ -75,4 +75,3 @@ if($btn == "국가방침 수정") { } header('location:b_dipcenter.php'); - diff --git a/hwe/js/dipcenter.js b/hwe/js/dipcenter.js deleted file mode 100644 index bcb49282..00000000 --- a/hwe/js/dipcenter.js +++ /dev/null @@ -1,135 +0,0 @@ - - - - -jQuery(function($){ - - function guiEditorInit($obj, editable){ - var $submitBtn = $obj.find('.submit'); - var $noticeInput = $obj.find('.input_form'); - var globalVariableName = $noticeInput.data('global'); - var $editForm = $obj.find('.edit_form'); - var $cancelEdit = $obj.find('.cancel_edit'); - - var editMode = false; - - function enableEditor(){ - editMode = true; - $cancelEdit.show(); - - var inputText = window[globalVariableName]; - if(!inputText || inputText == '

'){ - inputText = '


'; - } - - $editForm.removeClass('viewer').summernote({ - minHeight:200, - maxHeight:null, - focus:true, - lang:'ko-KR', - toolbar: [ - // [groupName, [list of button]] - ['do', ['undo', 'redo']], - ['style', ['bold', 'italic', 'underline', 'clear']], - ['font2', ['fontname', 'fontsize']], - ['font', ['strikethrough', 'superscript', 'subscript']], - ['color', ['color']], - ['in', ['picture', 'link', 'video', 'table', 'hr']], - ['para', ['ul', 'ol', 'paragraph']], - ['height', ['height', 'codeview']] - ], - popover: { - image: [ - ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], - ['float', ['floatLeft', 'floatRight', 'floatNone']], - ['remove', ['removeMedia']], - ['custom', ['imageFlip']], - ], - }, - fontNames: ['맑은 고딕', 'Nanum Gothic', 'Nanum Myeongjo', 'Nanum Pen Script', '굴림', '굴림체', '바탕', '바탕체', '궁서', '궁서체'], - fontSizes: ['8', '9', '10', '11', '12', '14', '16', '20', '24', '28', '32', '36', '40', '46', '52', '60'], - callbacks: { - onImageUpload: function(files) { - $editForm.summernote('saveRange'); - if(files.length == 0){ - alert('업로드된 파일이 없습니다.'); - return false; - } - - var formData = new FormData(); - formData.append('img', files[0]); - $editForm.summernote("pasteHtml", ''); - - $.ajax({ - type:'post', - url:'j_image_upload.php', - dataType:'json', - contentType: false, - processData:false, - data:formData - }).then(function(result){ - if(!result.result){ - alert(result.reason); - return; - } - - console.log($editForm.summernote('code')); - if($editForm.summernote('isEmpty')){ - - console.log('haha?'); - var $img = $(''); - $img.attr('src', result.path); - $editForm.summernote('code', $img); - return; - } - - $editForm.summernote("insertImage", result.path, result.path); - - },function(){ - alert('알 수 없는 이유로 아이콘 업로드를 실패했습니다.'); - }); - } - } - }).summernote('code', inputText); - } - - function disableEditor(){ - editMode = false; - $editForm.summernote('destroy'); - $cancelEdit.hide(); - $editForm.html(window[globalVariableName]).addClass('viewer'); - activeFlip($editForm); - } - - $cancelEdit.hide(); - $editForm.html(window[globalVariableName]); - activeFlip($editForm); - if(editable){ - $submitBtn.prop('disabled', false); - } - else{ - $submitBtn.prop('disabled', true); - } - - $submitBtn.click(function(e){ - if(!editMode){ - e.preventDefault(); - enableEditor(); - return false; - } - var text = $editForm.summernote('code'); - window[globalVariableName] = text; - $noticeInput.val(text); - }); - - $cancelEdit.click(function(e){ - e.preventDefault(); - disableEditor(); - }); - -} - -guiEditorInit($('#noticeForm'), editable); -guiEditorInit($('#scoutMsgForm'), editable); - -}) \ No newline at end of file diff --git a/hwe/ts/@types/summernote/dist/summernote-bs4.d.ts b/hwe/ts/@types/summernote/dist/summernote-bs4.d.ts new file mode 100644 index 00000000..5e9f208c --- /dev/null +++ b/hwe/ts/@types/summernote/dist/summernote-bs4.d.ts @@ -0,0 +1,326 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +// Type definitions for Summernote 0.8 +// Project: https://github.com/summernote/summernote#readme +// Definitions by: Wouter Staelens +// Denny Harijanto +// Corbin Crutchley +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.7 + +/// + +declare global { + namespace Summernote { + type fontSizeUnitOptions = 'px' | 'pt'; + + interface Options { + airMode?: boolean | undefined; + tabDisable?: boolean | undefined; + codeviewFilter?: boolean | undefined; + codeviewFilterRegex?: string | undefined; + codeviewIframeWhitelistSrc?: string[] | undefined; + codeviewIframeFilter?: boolean | undefined; + callbacks?: SummernoteCallbacks | SummernoteUndocumentedCallbacks | undefined; // todo + codemirror?: CodemirrorOptions | undefined; + colors?: colorsDef | undefined; + dialogsInBody?: boolean | undefined; + dialogsFade?: boolean | undefined; + direction?: string | undefined; + disableDragAndDrop?: boolean | undefined; + focus?: boolean | undefined; + fontNames?: string[] | undefined; + fontNamesIgnoreCheck?: string[] | undefined; + fontSizes?: string[] | undefined; + fontSizeUnits?: fontSizeUnitOptions[] | undefined; + height?: number | undefined; + hint?: HintOptions | undefined; + icons?: IconsOptions | undefined; + insertTableMaxSize?: InsertTableMaxSizeOptions | undefined; + keyMap?: KeyMapOptions | undefined; + lang?: string | undefined; + lineHeights?: string[] | undefined; + minHeight?: number | undefined; + maxHeight?: number | undefined; + maximumImageFileSize?: any; + modules?: ModuleOptions | undefined; + popover?: PopoverOptions | undefined; + placeholder?: string | undefined; + shortcuts?: boolean | undefined; + styleTags?: styleTagsOptions[] | undefined; + styleWithSpan?: boolean | undefined; + tabsize?: number | undefined; + tableClassName?: string | undefined; + textareaAutoSync?: boolean | undefined; + toolbar?: toolbarDef | undefined; + width?: number | undefined; + } + + type toolbarStyleGroupOptions = 'style' | 'bold' | 'italic' | 'underline' | 'clear'; + type toolbarFontGroupOptions = 'fontname' | 'fontsize' | 'fontsizeunit' | 'color' | 'forecolor' | 'backcolor' | 'bold' | 'italic' | 'underline' | 'strikethrough' | 'superscript' | + 'subscript' | 'clear'; + type toolbarFontsizeGroupOptions = 'fontsize' | 'fontname' | 'color'; + type toolbarColorGroupOptions = 'color'; + type toolbarParaGroupOptions = 'ul' | 'ol' | 'paragraph' | 'style' | 'height'; + type toolbarHeightGroupOptions = 'height'; + type toolbarTableGroupOptions = 'table'; + type toolbarInsertGroupOptions = 'link' | 'picture' | 'hr' | 'table' | 'video'; + type toolbarViewGroupOptions = 'fullscreen' | 'codeview' | 'help'; + type toolbarHelpGroupOptions = 'help'; + type miscGroupOptions = 'fullscreen' | 'codeview' | 'undo' | 'redo' | 'help'; + // type toolbarDef = [string, string[]][] + type toolbarDef = Array< + ['style', toolbarStyleGroupOptions[]] + | ['font', toolbarFontGroupOptions[]] + | ['fontname', toolbarFontNameOptions[]] + | ['fontsize', toolbarFontsizeGroupOptions[]] + | ['color', toolbarColorGroupOptions[]] + | ['para', toolbarParaGroupOptions[]] + | ['height', toolbarHeightGroupOptions[]] + | ['table', toolbarTableGroupOptions[]] + | ['insert', toolbarInsertGroupOptions[]] + | ['view', toolbarViewGroupOptions[]] + | ['help', toolbarHelpGroupOptions[]] + | ['misc', miscGroupOptions[]] + >; + + type colorsDef = Array<[string[]]>; + type styleTagsOptions = 'p' | 'blockquote' | 'pre' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + + interface InsertTableMaxSizeOptions { + col: number; + row: number; + } + + interface IconsOptions { + options?: any; // todo + } + + interface KeyMapOptions { + pc?: KeyMapPcOptions | undefined; + mac?: KeyMapMacOptions | undefined; + } + + interface KeyMapPcOptions { + options?: any; // todo + } + + interface KeyMapMacOptions { + options?: any; // todo + } + + type htmlElement = string; + + interface HintOptions { + words?: string[] | undefined; + mentions?: string[] | undefined; + match: RegExp; + search: (keyword: string, callback: (plausibleItems: string[]) => void) => void; + template?: ((item: string) => htmlElement) | undefined; + content?: ((item: string) => htmlElement | JQuery.Node) | undefined; + } + + interface CodemirrorOptions { + mode?: string | undefined; + htmlNode?: boolean | undefined; + lineNumbers?: boolean | undefined; + theme?: string | undefined; + } + + type popoverImageOptionsImagesize = 'imageSize100' | 'imageSize50' | 'imageSize25'; + type popoverImageOptionsFloat = 'floatLeft' | 'floatRight' | 'floatNone'; + type popoverImageOptionsRemove = 'removeMedia'; + type popoverImageDef = [ + ['imagesize', popoverImageOptionsImagesize[]], + ['float', popoverImageOptionsFloat[]], + ['remove', popoverImageOptionsRemove[]], + ['custom', string[]]?,//NOTE: 이 부분이 바뀜(Hide_D) + ]; + + type popoverLinkLinkOptions = 'linkDialogShow' | 'unlink'; + type popoverLinkDef = [ + ['link', popoverLinkLinkOptions[]] + ]; + + type popoverAirOptionsColor = 'color'; + type popoverAirOptionsFont = 'bold' | 'underline' | 'clear'; + type popoverAirOptionsPara = 'ul' | 'paragraph'; + type popoverAirOptionsTable = 'table'; + type popoverAirOptionsInsert = 'link' | 'picture'; + type popoverAirDef = [ + ['color', popoverAirOptionsColor], + ['font', popoverAirOptionsFont], + ['para', popoverAirOptionsPara], + ['table', popoverAirOptionsTable], + ['insert', popoverAirOptionsInsert] + ]; + + interface PopoverOptions { + image?: popoverImageDef | undefined; + link?: popoverLinkDef | undefined; + air?: popoverAirDef | undefined; + } + + interface ModuleOptions { + options?: any; // todo + } + + interface CreateLinkOptions { + text: string; + url: string; + newWindow: boolean; + } + + type EditImageCallback = ($image: JQuery.Node) => void; + + type toolbarFontNameOptions = string; + + interface SummernoteCallbacks { + onBeforeCommand?: (contents: string) => void; + onChange?: (contents: string, $editable: JQuery) => void; + onChangeCodeview?: (code: string, $editor: JQuery) => void; + onDialogShown?: () => void; + onEnter?: (ev: Event) => void; + onFocus?: (ev: Event) => void; + onBlur?: (ev: Event) => void; + onBlurCodeview?: (code: string, ev: Event) => void; + onImageLinkInsert?: (url: string) => void; + onImageUpload?: (files: Blob[]) => void; + onImageUploadError?: (err: any) => void; + onInit?: () => void; + onKeyup?: (ev: KeyboardEvent) => void; + onKeydown?: (ev: KeyboardEvent) => void; + onMouseDown?: (ev: MouseEvent) => void; + onMouseUp?: (ev: MouseEvent) => void; + onPaste?: (e: Event) => void; + onScroll?: (e: Event) => void; + } + + type SummernoteUndocumentedCallbacks = { + [key in Exclude]: (...args: any[]) => void; + }; + + interface Plugin{ + showLinkDialog(...args:any[]); + show: () => void; + bindEnterKey: ($input: JQuery, $btn: JQuery) => void; + destroy: () => void; + $dialog: JQuery; + initialize: () => void; + } + + interface Context { + //src/js/base/Context.js + triggerEvent(namespace: string, ...args:any[]); + options: any; + invoke(arg0: string); + memo(arg0: string, arg1: () => any); + layoutInfo: { + note: JQuery, + editor: JQuery, + editable: JQuery, + toolbar: JQuery, + } + } + + interface UI{ + showDialog($dialog: JQuery); + onDialogHidden($dialog: JQuery, arg1: () => void); + onDialogShown($dialog: JQuery, arg1: () => void); + hideDialog($dialog: JQuery); + dialog(arg0: { title: any; body: string; footer: string; }); + button: (...args:any[])=>any, + icon: (...args:any[])=>any, + } + } + + interface JQueryStatic{ + summernote: { + lang: Record>, + options: Record, + plugins: Record, + ui: Summernote.UI, + }; + } + + interface JQuery { + summernote(): JQuery; + summernote(command: string): JQuery; + summernote(options?: Summernote.Options): JQuery; + summernote(command: string, markupString: string): JQuery; + summernote(command: string, value: number): JQuery; + summernote(command: string, node: JQuery.Node): JQuery; + summernote(command: string, url: string, filename?: (string | Summernote.EditImageCallback)): JQuery; + + summernote(command: 'destroy'): JQuery; + summernote(command: 'code'): string; + summernote(command: 'code', markupStr: string): undefined; + summernote(command: 'editor.pasteHTML' | 'pasteHTML', markup: string): JQuery; + + // Basic API + summernote(command: 'editor.createRange' | 'createRange'): JQuery; + summernote(command: 'editor.saveRange' | 'saveRange'): JQuery; + summernote(command: 'editor.restoreRange' | 'restoreRange'): JQuery; + summernote(command: 'editor.undo' | 'undo'): JQuery; + summernote(command: 'editor.redo' | 'redo'): JQuery; + summernote(command: 'editor.focus' | 'focus'): JQuery; + summernote(command: 'editor.isEmpty' | 'isEmpty'): boolean; + summernote(command: 'reset'): JQuery; + summernote(command: 'disable'): JQuery; + summernote(command: 'enable'): JQuery; + // Font style API + summernote(fontStyle: 'editor.bold' | 'bold'): JQuery; + summernote(fontStyle: 'editor.italic' | 'italic'): JQuery; + summernote(fontStyle: 'editor.underline' | 'underline'): JQuery; + summernote(fontStyle: 'editor.strikethrough' | 'strikethrough'): JQuery; + summernote(command: 'editor.superscript' | 'superscript'): JQuery; + summernote(command: 'editor.subscript' | 'subscript'): JQuery; + summernote(command: 'editor.removeFormat' | 'removeFormat'): JQuery; + summernote(command: 'backColor', color: string): JQuery; + summernote(command: 'foreColor', color: string): JQuery; + summernote(command: 'fontName', fontName: string): JQuery; + summernote(command: 'editor.fontSize' | 'fontSize', fontSize: number): JQuery; + // Paragraph API + summernote(command: 'editor.justifyLeft' | 'justifyLeft'): JQuery; + summernote(command: 'editor.justifyRight' | 'justifyRight'): JQuery; + summernote(command: 'editor.justifyCenter' | 'justifyCenter'): JQuery; + summernote(command: 'editor.justifyFull' | 'justifyFull'): JQuery; + summernote(command: 'insertParagraph'): JQuery; + summernote(command: 'editor.insertOrderedList' | 'insertOrderedList'): JQuery; + summernote(command: 'editor.insertUnorderedList' | 'insertUnorderedList'): JQuery; + summernote(command: 'editor.indent' | 'indent'): JQuery; + summernote(command: 'editor.outdent' | 'outdent'): JQuery; + summernote(command: 'formatPara'): JQuery; + summernote(command: 'formatH1'): JQuery; + summernote(command: 'formatH2'): JQuery; + summernote(command: 'formatH3'): JQuery; + summernote(command: 'formatH4'): JQuery; + summernote(command: 'formatH5'): JQuery; + summernote(command: 'formatH6'): JQuery; + // Insertion API + summernote(command: 'editor.insertImage' | 'insertImage', url: string, filename?: (string | Summernote.EditImageCallback)): JQuery; + summernote(command: 'editor.insertNode' | 'insertNode', node: JQuery.Node): JQuery; + summernote(command: 'editor.insertText' | 'insertText', text: string): JQuery; + summernote(command: 'createLink', options: Summernote.CreateLinkOptions): JQuery; + // TODO: Callbacks + + // TODO: Editor + // editor.insertImagesOrCallback ?? + // editor.afterCommand ?? + // editor.resizeTo ?? + // editor.resize ?? + // editor.saveTarget ?? + // editor.isActivated ?? + // editor.formatBlock ?? + // editor.color ?? + // editor.lineHeight ?? + // editor.insertTable ?? + // editor.insertHorizontalRule ?? + // editor.floatMe ?? + // editor.removeMedia ?? + // editor.currentStyle ?? + // editor.getLinkInfo ?? + // editor.getSelectedText ?? + } +} + +export { }; diff --git a/hwe/ts/common_deprecated.ts b/hwe/ts/common_deprecated.ts index 569f3a09..da2d74b4 100644 --- a/hwe/ts/common_deprecated.ts +++ b/hwe/ts/common_deprecated.ts @@ -1,4 +1,4 @@ -import { activeFlip, isBrightColor, getIconPath, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy"; +import { activateFlip, isBrightColor, getIconPath, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy"; import { mb_strwidth } from "./util/mb_strwidth"; import { TemplateEngine } from "./util/TemplateEngine"; import { escapeHtml } from "./legacy/escapeHtml"; @@ -11,7 +11,7 @@ exportWindow(jQuery, 'jQuery'); jQuery(function ($) { initTooltip(); - activeFlip(); + activateFlip(); const customCSS = localStorage.getItem('sam_customCSS'); if (customCSS) { @@ -34,7 +34,7 @@ exportWindow(mb_strwidth, 'mb_strwidth'); exportWindow(isBrightColor, 'isBrightColor'); exportWindow(TemplateEngine, 'TemplateEngine'); exportWindow(getIconPath, 'getIconPath'); -exportWindow(activeFlip, 'activeFlip'); +exportWindow(activateFlip, 'activateFlip'); exportWindow(errUnknown, 'errUnknown'); exportWindow(errUnknownToast, 'errUnknownToast'); exportWindow(quickReject, 'quickReject'); diff --git a/hwe/ts/common_legacy.ts b/hwe/ts/common_legacy.ts index 6a89fce3..754ed4d4 100644 --- a/hwe/ts/common_legacy.ts +++ b/hwe/ts/common_legacy.ts @@ -100,7 +100,7 @@ export function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string { } } -export function activeFlip($obj?: JQuery): void { +export function activateFlip($obj?: JQuery): void { let $result: JQuery; if ($obj === undefined) { $result = $('img[data-flip]'); diff --git a/hwe/ts/dipcenter.ts b/hwe/ts/dipcenter.ts new file mode 100644 index 00000000..589206c5 --- /dev/null +++ b/hwe/ts/dipcenter.ts @@ -0,0 +1,150 @@ +import $ from 'jquery'; +import Popper from 'popper.js'; +(window as unknown as { Popper: unknown }).Popper = Popper;//XXX: 왜 popper를 이렇게 불러야 하는가? +import 'bootstrap'; +import 'summernote/dist/summernote-bs4'; +import 'summernote/dist/summernote-bs4.css'; +import './summernote-image-flip'; +import { activateFlip } from './common_legacy'; +import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest'; + +declare const editable: boolean; + +declare const storedData: { + nationMsg: string, + scoutMsg: string, +} + +$(function ($) { + setAxiosXMLHttpRequest(); + function guiEditorInit($obj: JQuery, editable: boolean) { + const $submitBtn = $obj.find('.submit'); + const $noticeInput = $obj.find('.input_form'); + const globalVariableName: 'nationMsg' | 'scoutMsg' = $noticeInput.data('global'); + const $editForm = $obj.find('.edit_form'); + const $cancelEdit = $obj.find('.cancel_edit'); + + let editMode = false; + + function enableEditor() { + editMode = true; + $cancelEdit.show(); + + let inputText = storedData[globalVariableName]; + if (!inputText || inputText == '

') { + inputText = '


'; + } + + $editForm.removeClass('viewer').summernote({ + minHeight: 200, + maxHeight: undefined, + focus: true, + lang: 'ko-KR', + toolbar: [ + // [groupName, [list of button]] + ['misc', ['undo', 'redo']], + ['style', ['bold', 'italic', 'underline', 'clear']], + ['fontname', ['fontname', 'fontsize']], + ['font', ['strikethrough', 'superscript', 'subscript']], + ['color', ['color']], + ['insert', ['picture', 'link', 'video', 'table', 'hr']], + ['para', ['ul', 'ol', 'paragraph']], + ['height', ['height']], + ['misc', ['codeview']] + ], + popover: { + image: [ + ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], + ['float', ['floatLeft', 'floatRight', 'floatNone']], + ['remove', ['removeMedia']], + ['custom', ['imageFlip']], + ], + }, + fontNames: ['맑은 고딕', 'Nanum Gothic', 'Nanum Myeongjo', 'Nanum Pen Script', '굴림', '굴림체', '바탕', '바탕체', '궁서', '궁서체'], + fontSizes: ['8', '9', '10', '11', '12', '14', '16', '20', '24', '28', '32', '36', '40', '46', '52', '60'], + callbacks: { + onImageUpload: function (files) { + $editForm.summernote('saveRange'); + if (files.length == 0) { + alert('업로드된 파일이 없습니다.'); + return false; + } + + const formData = new FormData(); + formData.append('img', files[0]); + $editForm.summernote("pasteHtml", ''); + + $.ajax({ + type: 'post', + url: 'j_image_upload.php', + dataType: 'json', + contentType: false, + processData: false, + data: formData + }).then(function (result) { + if (!result.result) { + alert(result.reason); + return; + } + + console.log($editForm.summernote('code')); + if ($editForm.summernote('isEmpty')) { + + console.log('haha?'); + const $img = $(''); + $img.attr('src', result.path); + $editForm.summernote('code', $img.html()); + return; + } + + $editForm.summernote("insertImage", result.path, result.path); + + }, function () { + alert('알 수 없는 이유로 아이콘 업로드를 실패했습니다.'); + }); + } + } + }).summernote('code', inputText); + } + + function disableEditor() { + editMode = false; + $editForm.summernote('destroy'); + $cancelEdit.hide(); + $editForm.html(storedData[globalVariableName]).addClass('viewer'); + activateFlip($editForm); + } + + $cancelEdit.hide(); + $editForm.html(storedData[globalVariableName]); + activateFlip($editForm); + if (editable) { + $submitBtn.prop('disabled', false); + } + else { + $submitBtn.prop('disabled', true); + } + + $submitBtn.click(function (e) { + if (!editMode) { + e.preventDefault(); + enableEditor(); + return false; + } + const text = $editForm.summernote('code'); + storedData[globalVariableName] = text; + $noticeInput.val(text); + }); + + $cancelEdit.click(function (e) { + e.preventDefault(); + disableEditor(); + }); + + } + + guiEditorInit($('#noticeForm'), editable); + guiEditorInit($('#scoutMsgForm'), editable); + activateFlip(); + +}) \ No newline at end of file diff --git a/hwe/ts/main.ts b/hwe/ts/main.ts index f69806bd..6acf9cbe 100644 --- a/hwe/ts/main.ts +++ b/hwe/ts/main.ts @@ -6,7 +6,7 @@ import { parseTime } from './util/parseTime'; import { addMilliseconds, addMinutes, differenceInMilliseconds } from 'date-fns'; import { formatTime } from './util/formatTime'; import { unwrap_any } from './util/unwrap_any'; -import { errUnknown } from './common_legacy'; +import { activateFlip, errUnknown } from './common_legacy'; import { unwrap } from './util/unwrap'; import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest'; import './msg.ts'; @@ -194,4 +194,5 @@ $(function ($) { setInterval(myclock, 500); reloadCommandList(); + activateFlip(); }); \ No newline at end of file diff --git a/hwe/ts/summernote-image-flip.ts b/hwe/ts/summernote-image-flip.ts new file mode 100644 index 00000000..874b2053 --- /dev/null +++ b/hwe/ts/summernote-image-flip.ts @@ -0,0 +1,153 @@ +/* Forked from https://github.com/asiffermann/summernote-image-title */ +import $ from 'jquery'; +import 'summernote/dist/summernote-bs4.js'; + +$(function ($) { + console.log($.summernote); + $.extend(true, $.summernote.lang, { + 'en-US': { + imageFlip: { + edit: 'Flip image', + flipLabel: 'Alternative Image' + } + }, + 'ko-KR': { + imageFlip: { + edit: '이미지 전환', + flipLabel: '대체 이미지( , 로 구분)' + } + }, + }); + $.extend($.summernote.options, { + imageFlip: { + icon: '', + tooltip: 'Image Flip' + } + }); + $.extend($.summernote.plugins, { + 'imageFlip': function (this: Summernote.Plugin, context: Summernote.Context) { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const self = this; + + const ui: Summernote.UI = $.summernote.ui; + const $note = context.layoutInfo.note; + const $editor = context.layoutInfo.editor; + const $editable = context.layoutInfo.editable; + const $toolbar = context.layoutInfo.toolbar; + + if (typeof context.options.imageFlip === 'undefined') { + context.options.imageFlip = {}; + } + + const options = context.options; + const lang = options.langInfo; + + context.memo('button.imageFlip', function () { + const button = ui.button({ + contents: ui.icon(options.icons.pencil), + container: false, + tooltip: lang.imageFlip.edit, + click: function (e: JQuery.Event) { + context.invoke('imageFlip.show'); + } + }); + + return button.render(); + }); + + this.initialize = function () { + const $container = options.dialogsInBody ? $(document.body) : $editor; + + const body = '
' + + '' + + '' + + '
'; + + const footer = ''; + + this.$dialog = ui.dialog({ + title: lang.imageFlip.edit, + body: body, + footer: footer + }).render().appendTo($container); + }; + + this.destroy = function () { + ui.hideDialog(this.$dialog); + this.$dialog.remove(); + }; + + this.bindEnterKey = function ($input, $btn) { + $input.on('keypress', function (event) { + if (event.keyCode === 13) { + $btn.trigger('click'); + } + }); + }; + + + type ImgInfo = { + imgDom: JQuery; + flip: string; + } + + this.show = function () { + const $img = $($editable.data('target')); + + const imgInfo = { + imgDom: $img, + flip: $img.data('flip'), + }; + + + this.showLinkDialog(imgInfo).then(function (imgInfo: ImgInfo) { + ui.hideDialog(self.$dialog); + const $img = imgInfo.imgDom; + + if (imgInfo.flip) { + $img.attr('data-flip', imgInfo.flip); + } + else { + $img.removeData('flip'); + } + + $note.val(context.invoke('code')); + $note.change(); + }); + }; + + this.showLinkDialog = function (imgInfo: ImgInfo) { + return $.Deferred(function (deferred) { + const $imageFlip = self.$dialog.find('.note-image-flip-text'); + const $editBtn = self.$dialog.find('.note-image-flip-btn'); + + ui.onDialogShown(self.$dialog, function () { + context.triggerEvent('dialog.shown'); + + $editBtn.click(function (event) { + event.preventDefault(); + void deferred.resolve({ + imgDom: imgInfo.imgDom, + flip: $imageFlip.val(), + }); + }); + + $imageFlip.val(imgInfo.flip).trigger('focus'); + self.bindEnterKey($imageFlip, $editBtn); + + }); + + ui.onDialogHidden(self.$dialog, function () { + $editBtn.off('click'); + + if (deferred.state() === 'pending') { + void deferred.reject(); + } + }); + + ui.showDialog(self.$dialog); + }); + }; + } + }); +}) \ No newline at end of file diff --git a/package.json b/package.json index c9e88280..b6133b49 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", + "buildDev": "webpack --mode=development", "watch": "webpack watch --mode=development", "watchProd": "webpack watch", "lint": "eslint hwe/ts ts" @@ -21,6 +22,7 @@ "@types/downloadjs": "^1.4.2", "@types/linkifyjs": "^2.1.4", "@types/select2": "^4.0.54", + "@types/summernote": "^0.8.6", "async-validator": "^4.0.2", "axios": "^0.21.1", "bootstrap": "^4.6.0", @@ -33,6 +35,7 @@ "lodash": "^4.17.21", "query-string": "^7.0.1", "select2": "^4.0", + "summernote": "^0.8.18", "vue": "^3.2.2" }, "devDependencies": { diff --git a/webpack.config.cjs b/webpack.config.cjs index 26c14ad8..83bbb6bf 100644 --- a/webpack.config.cjs +++ b/webpack.config.cjs @@ -34,6 +34,7 @@ module.exports = (env, argv) => { myPage: '@/myPage.ts', extExpandCity: '@/extExpandCity.ts', main: '@/main.ts', + dipcenter: '@/dipcenter.ts', //FORM 입력용, frontend 변경후 제거