Files
2025-07-02 14:13:16 +09:00

220 lines
7.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

let uploadedImages = [];
// 업로드 시 Nonce 값이 없으면 iframe에서 요청 후 대기
async function uploadImage(file, options = { insert: true }) {
if (typeof file === 'string') {
// SVG 파일은 변환하지 않고 바로 업로드
if (file.endsWith(".svg")) {
//console.log("SVG 파일 감지:", file);
} else {
file = await convertImageUrlToFile(file);
}
}
if (!(file instanceof File)) {
//console.error("올바른 이미지 파일이 아닙니다:", file);
alert("이미지 파일을 선택해주세요.");
return;
}
if (!ed_nonce) {
ed_nonce = await requestNonceFromParent();
}
if (!ed_nonce) {
alert("보안 토큰이 유효하지 않습니다. 새로고침 후 다시 시도해주세요.");
return;
}
// ✅ 로딩 오버레이 표시
const loadingOverlay = document.querySelector('.loadingOverlay.loadingOverlay_ai');
if (loadingOverlay) {
loadingOverlay.style.display = 'block';
}
const formData = new FormData();
formData.append("file", file);
formData.append("editor_nonce", ed_nonce);
return new Promise((resolve, reject) => {
$.ajax({
url: g5Config.g5_editor_url + "/php/rb.upload.php",
type: "POST",
data: formData,
contentType: false,
processData: false,
dataType: "json",
success: function (response) {
if (response.files && response.files[0] && response.files[0].url) {
let imageUrl = response.files[0].url;
// 업로드 성공 후 로딩 숨김
if (loadingOverlay) {
loadingOverlay.style.display = 'none';
}
// SVG 업로드 후 처리
//console.log("업로드 성공:", imageUrl);
// 일반 첨부용일 때만 insertImage() 호출
if (options.insert) {
insertImage(imageUrl);
}
resolve(imageUrl);
} else {
alert("이미지 업로드에 실패 하였습니다.");
reject("이미지 업로드에 실패 하였습니다");
}
},
error: function (error) {
console.error("이미지 업로드 실패:", error);
reject(error);
},
complete: function () {
// ✅ 업로드가 끝나면 무조건 로딩 숨김
if (loadingOverlay) {
loadingOverlay.style.display = 'none';
}
}
});
});
}
$('#editor').on('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass('dragover');
});
$('#editor').on('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass('dragover');
});
$('#editor').on('drop', function (e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass('dragover');
const files = e.originalEvent.dataTransfer.files;
if (!files.length) return;
for (let i = 0; i < files.length; i++) {
uploadImage(files[i]);
}
});
// 파일 선택 이미지 업로드 (input[type="file"])
$('#image-upload').change(function (event) {
const files = event.target.files;
if (!files.length) return;
for (let i = 0; i < files.length; i++) {
uploadImage(files[i]);
}
$('#image-upload').val('');
});
function insertImage(imageUrl) {
const img = document.createElement('img');
img.src = imageUrl;
img.alt = "Uploaded Image";
img.crossOrigin = "anonymous";
img.draggable = false; // 드래그 방지
img.style.width = '100%'; // 가로는 부모 요소에 맞춤
img.onload = function () {
// 이미지의 원본 크기
const imgWidth = img.naturalWidth;
const imgHeight = img.naturalHeight;
// dataratio는 이미지의 원본 높이/원본 너비
const ratio = imgHeight / imgWidth;
const editor = document.getElementById('editor');
const editorWidth = editor.offsetWidth; // 에디터의 가로 크기
// .resizable_wrap 생성
const wrap = document.createElement('div');
wrap.classList.add('resizable_wrap');
// .resizable div 생성
const wrapper = document.createElement('div');
wrapper.classList.add('resizable');
// 에디터보다 클 경우 100%, 작으면 원본 크기 사용하여 width 설정
if (imgWidth > editorWidth) {
wrapper.style.width = '100%';
} else {
wrapper.style.width = `${imgWidth}px`;
}
// 원본 크기를 data 속성에 저장 (항상 갱신)
wrapper.dataset.originalWidth = imgWidth;
wrapper.dataset.originalHeight = imgHeight;
wrapper.dataset.ratio = ratio;
// 초기 높이 계산 (현재 width에 dataratio를 곱함)
wrapper.style.height = `${wrapper.offsetWidth * ratio}px`;
// 크기 조절 핸들 추가
const resizeHandle = document.createElement('div');
resizeHandle.classList.add('resize-handle');
// 이미지와 핸들 추가
wrapper.appendChild(img);
wrapper.appendChild(resizeHandle);
wrap.appendChild(wrapper);
// 줄바꿈용 <p><br></p> 추가
const paragraph = document.createElement('p');
paragraph.appendChild(document.createElement('br'));
// 현재 커서 위치 확인 후 에디터 내 삽입
const selection = window.getSelection();
const range = selection.rangeCount ? selection.getRangeAt(0) : null;
if (range) {
let container = range.commonAncestorContainer;
if (container.nodeType === Node.TEXT_NODE) {
container = container.parentElement;
}
if ($(container).closest('#editor').length) {
range.deleteContents();
range.insertNode(wrap);
wrap.parentNode.insertBefore(paragraph, wrap.nextSibling);
range.setStart(paragraph, 0);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
} else {
editor.appendChild(wrap);
editor.appendChild(paragraph);
}
} else {
editor.appendChild(wrap);
editor.appendChild(paragraph);
}
// 갱신: 현재 wrapper의 높이를 dataratio에 따라 재계산
wrapper.style.height = `${wrapper.offsetWidth * ratio}px`;
// 창 크기가 변경될 때 높이 업데이트
function updateHeight() {
const currentWidth = wrapper.offsetWidth;
const originalWidth = parseFloat(wrapper.dataset.originalWidth) || currentWidth;
const originalHeight = parseFloat(wrapper.dataset.originalHeight) || currentWidth * ratio;
const originalRatio = parseFloat(wrapper.dataset.ratio) || (originalHeight / originalWidth);
wrapper.style.height = `${currentWidth * originalRatio}px`;
}
window.addEventListener("resize", updateHeight);
// 크기 조절 기능 활성화 (이 함수 내에서 리사이즈 후에도 data속성이 갱신되도록 구현 가능)
makeImageResizableWithObserver($(wrapper));
};
}