This commit is contained in:
2025-08-05 16:14:01 +09:00
parent d6ea6dc154
commit 4dfc39751b
5 changed files with 237 additions and 158 deletions
@@ -6,34 +6,80 @@
layout:decorate="~{layout/default_layout}"
>
<th:block layout:fragment="head">
<script type="text/javascript" th:src="@{/js/toast-ui-view.js}"></script>
<link th:href="@{/css/toast-ui-dark.css}" rel="stylesheet" />
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
<link th:href="@{/css/blog.css}" rel="stylesheet" />
<!-- Quill 스타일 시트 -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<!-- Quill 라이브러리 -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<!-- HTML 에디터 영역 -->
<!-- <div id="editor-container" style="height: 300px;"></div>-->
<!-- Quill 라이브러리 및 테마 -->
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<!-- 테이블 플러그인 CSS & JS -->
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script th:inline="javascript">
let editor
let onChange = () => {console.log(editor.getMarkdown())}
document.addEventListener("DOMContentLoaded", onLoaded);
function onLoaded() {
var quill = null
document.addEventListener('DOMContentLoaded', function() {
const editorContainer = document.querySelector('#editor');
function setEditorHeight() {
const height = Math.max(window.innerHeight * 0.5, 300);
editorContainer.style.height = height + 'px';
}
baseData.title = [[${srcPost.title}]];
baseData.content = [[${srcPost.content}]];
baseData.firstPostLon = [[${srcPost.firstPostLon}]];
baseData.firstPostLat = [[${srcPost.firstPostLat}]];
document.getElementById('location_field').textContent = "Lat: " + baseData.firstPostLat + ", Lon: " + baseData.firstPostLon;
var requestOptions = {
method: 'GET',
};
fetch("https://api.geoapify.com/v1/geocode/reverse?lat="+baseData.firstPostLat+"&lon="+baseData.firstPostLon+"&apiKey=2b37a75bb0754086b5a1c4a7c3173ee8", requestOptions)
.then(response => response.json())
.then(function(result) {
try {
document.getElementById('location_field').textContent = result.features[0].properties.formatted
} catch (e) {
document.getElementById('location_field').innerHTML = "Lat: " + baseData.firstPostLat + "<br> Lon: " + baseData.firstPostLon;
}
})
.catch(error => console.log('error', error));
$('#title_layer').text(baseData.title)
editor = new toastui.Editor({
el: document.querySelector('#editor'),
height: '100%',
width:'100%',
viewer: true,
usageStatistics : false,
initialValue:baseData.content,
setEditorHeight();
window.addEventListener('resize', setEditorHeight);
var Font = Quill.import('formats/font');
Font.whitelist = ['sans-serif', 'serif', 'monospace', 'arial', 'georgia', 'comic-sans-ms', 'courier-new','roboto', 'playfair-display'];
Quill.register(Font, true);
Quill.register({ 'modules/table-better': QuillTableBetter }, true);
quill = new Quill(editorContainer, {
theme: 'snow',
modules: {
toolbar: [],
'table-better': {
language: 'en_US',
toolbarTable: true
},
keyboard: {
bindings: QuillTableBetter.keyboardBindings
}
}
});
}
function loadEditor() {
goToEditor([[${srcPost.id}]]);
}
quill.enable(false)
if (isDelta(baseData.content)) {
quill.setContents(baseData.content); // Delta 데이터라면 setContents
} else {
quill.clipboard.dangerouslyPasteHTML(baseData.content); // HTML 데이터라면 dangerouslyPasteHTML
}
document.querySelector('.ql-toolbar').style.display = 'none';
});
</script>
</th:block>
<th:block layout:fragment="content" id="content">
@@ -62,7 +108,7 @@
<div style="width: 15px" ></div>
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
<div style="width: 15px" ></div>
<label class="write_option" readonly id="location_field"></label>
<div class="write_option" id="location_field" ></div>
</div>
<h3 id="write" th:text="${srcPost.firstAddress}"></h3>
<h3 id="modify" th:text="${srcPost.modifyAddress}"></h3>
@@ -6,119 +6,95 @@
layout:decorate="~{layout/default_layout}"
>
<th:block layout:fragment="head" id="head">
<script type="text/javascript" th:src="@{/js/toast-ui.js}"></script>
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
<link th:href="@{/css/blog.css}" rel="stylesheet" />
<link th:href="@{/css/toast-ui.css}" rel="stylesheet" />
<link th:href="@{/css/toast-ui-dark.css}" rel="stylesheet" />
<!-- <link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor-dark.css" />-->
<script th:inline="javascript">
var editor
let onChange = () => {console.log(editor.getMarkdown())}
document.addEventListener("DOMContentLoaded", onLoaded);
function onLoaded() {
var currentTitle = [[${defaultTitle}]]
getLocation()
var titleField = document.getElementById('title_field')
titleField.addEventListener("change", (event) => {
baseData.title = titleField.value
console.log(baseData.title)
});
titleField.value = currentTitle
var style = getComputedStyle(document.body)
console.log(style.getPropertyValue('--ContentVerticalMargin'))
console.log(window.c)
console.log(style.getPropertyValue('--FooterHeight'))
console.log(style.getPropertyValue('--TopHeight'))
var editorHeght = (
document.querySelector('#main_layer').getBoundingClientRect().height * 0.7
)
<!-- Quill 스타일 시트 -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
editor = new toastui.Editor({
el: document.querySelector('#editor'),
previewStyle: 'tab',
height: editorHeght + 'px',
width:'95%',
theme:'dark',
usageStatistics : false,
toolbar:null,
initialValue:
"# 제목 " +"\n" +
"평문 사이에 **볼드체** *이탤릭체*"+"\n" +
"~~어디쓰지~~"+"\n" +
"***"+"\n" +
"### 모라모라 " +"\n" +
"> 으흐흠..." +"\n" +
"* 쓸까?" +"\n" +
"1. 첫번째" +"\n" +
"* [x] 체크하자" +"\n" +
"* [ ] 체크하자" +"\n" +
" \|dd\|cc\|ff\|\n" +
" \|\-\-\-\|\-\-\-\|\-\-\-\|\n" +
" \|aa\|s\|s\|" +"\n" +
"[링크다](https://youtube.com)" +"\n" +
"`var test = 'real test'`" +"\n" +
"```\n" +
"let test= = 'real test'\n" +
"```"
,
theme:"dark",
initialEditType:"wysiwyg",
hooks: {
addImageBlobHook: (blob, callback) => {
const formData = new FormData();
formData.append('file', blob);
let uploadUrl = getMainPath() + "/blog/post/imageUpload";
let imageUrl = getMainPath() + '/blog/post/images/';
$.ajax({
type: 'POST',
enctype: 'multipart/form-data',
url: uploadUrl,
data: formData,
dataType: 'json',
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
imageUrl += data.fileName;
callback(imageUrl, '사진 대체 텍스트 입력');
},
error: function (e) {
callback('image_load_fail', '사진 대체 텍스트 입력');
}
});
<!-- Quill 라이브러리 -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<!-- HTML 에디터 영역 -->
<!-- <div id="editor-container" style="height: 300px;"></div>-->
<!-- Quill 라이브러리 및 테마 -->
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<!-- 테이블 플러그인 CSS & JS -->
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script>
var quill = null
document.addEventListener('DOMContentLoaded', function() {
const editorContainer = document.querySelector('#editor');
function setEditorHeight() {
const height = Math.max(window.innerHeight * 0.5, 300);
editorContainer.style.height = height + 'px';
}
setEditorHeight();
window.addEventListener('resize', setEditorHeight);
var Font = Quill.import('formats/font');
Font.whitelist = ['sans-serif', 'serif', 'monospace', 'arial', 'georgia', 'comic-sans-ms', 'courier-new','roboto', 'playfair-display'];
Quill.register(Font, true);
Quill.register({ 'modules/table-better': QuillTableBetter }, true);
quill = new Quill(editorContainer, {
theme: 'snow',
modules: {
toolbar: [
[{ font: Font.whitelist }], // 폰트 목록 드롭다운 추가
[{ 'size': ['small', false, 'large', 'huge'] }], // 폰트 크기
['bold', 'italic', 'underline', 'strike'], // 글자 굵기, 기울임, 밑줄, 취소선
[{ 'color': [] }, { 'background': [] }], // 글자 색, 배경색
[{ 'header': 1 }, { 'header': 2 }, 'blockquote', 'code-block'], // 제목1,2, 인용, 코드 블록
[{ 'script': 'sub'}, { 'script': 'super' }], // 위첨자, 아래첨자
[{ 'list': 'ordered'}, { 'list': 'bullet' }], // 번호 있는 목록, 점 목록
[{ 'indent': '-1'}, { 'indent': '+1' }], // 들여쓰기 증가/감소
['link', 'image', 'video'],
['table-better'],// 링크, 이미지, 비디오
[{ 'direction': 'rtl' }], // 텍스트 방향 (오른쪽 → 왼쪽)
[{ 'align': [] }], // 정렬 옵션
['clean']
],
'table-better': {
language: 'en_US',
toolbarTable: true
},
keyboard: {
bindings: QuillTableBetter.keyboardBindings
}
}
});
}
function save() {
console.log(editor.getHTML())
console.log(editor.getMarkdown())
onclickWrite([[${enc}]],[[${keyword}]],editor.getMarkdown())
}
});
</script>
</th:block>
<th:block layout:fragment="content" id="content">
<div id="main_layer">
<th:block sec:authorize="isAnonymous()">
<h1>권한이 없는 뎁쇼?!</h1>
</th:block>
<th:block sec:authorize="isAuthenticated()">
<div class="layer">
<input id="title_field" class="write_option" />
<section class="wrapper style1">
<div class="container">
<div id="content">
<article>
<th:block sec:authorize="isAnonymous()">
<h1>권한이 없는 뎁쇼?!</h1>
</th:block>
<th:block sec:authorize="isAuthenticated()">
<div class="layer">
<input id="title_field" class="write_option" />
</div>
<div id="editor" ></div>
<div class="write_controllbox">
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
<div style="width: 15px" ></div>
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
<div style="width: 15px" ></div>
<label class="write_option" readonly id="location_field"></label>
</div>
<h1><button id="save" class="write_option" style="width: 100%; position: relative" onclick="save()">저장하셈</button></h1>
</th:block>
</article>
</div>
</div>
<div id="editor" ></div>
<div class="write_controllbox">
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
<div style="width: 15px" ></div>
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
<div style="width: 15px" ></div>
<label class="write_option" readonly id="location_field"></label>
</div>
<h1><button id="save" class="write_option" style="width: 100%; position: relative" onclick="save()">저장하셈</button></h1>
</th:block>
</section>
</div>
</th:block>
<th:block layout:fragment="popup_layer">