/** * DocumentLoader 모듈 * 문서/노트 로딩 및 네비게이션 관리 */ class DocumentLoader { constructor(api) { this.api = api; // 캐싱된 API 사용 (사용 가능한 경우) this.cachedApi = window.cachedApi || api; console.log('📄 DocumentLoader 초기화 완료 (캐싱 API 적용)'); } /** * 노트 로드 */ async loadNote(documentId) { try { console.log('📝 노트 로드 시작:', documentId); // 백엔드에서 노트 정보 가져오기 const noteDocument = await this.api.get(`/note-documents/${documentId}`); // 노트 제목 설정 document.title = `${noteDocument.title} - Document Server`; // 노트 내용을 HTML로 설정 const contentElement = document.getElementById('document-content'); if (contentElement && noteDocument.content) { contentElement.innerHTML = noteDocument.content; } console.log('📝 노트 로드 완료:', noteDocument.title); return noteDocument; } catch (error) { console.error('노트 로드 실패:', error); throw new Error('노트를 불러올 수 없습니다'); } } /** * 문서 로드 (실제 API 연동) */ async loadDocument(documentId) { try { // 백엔드에서 문서 정보 가져오기 (캐싱 적용) const docData = await this.cachedApi.get(`/documents/${documentId}`, { content_type: 'document' }, { category: 'document' }); // HTML 파일 경로 구성 (백엔드 서버를 통해 접근) const htmlPath = docData.html_path; const fileName = htmlPath.split('/').pop(); const response = await fetch(`http://localhost:24102/uploads/documents/${fileName}`); if (!response.ok) { throw new Error('문서 파일을 불러올 수 없습니다'); } const htmlContent = await response.text(); document.getElementById('document-content').innerHTML = htmlContent; // 페이지 제목 업데이트 document.title = `${docData.title} - Document Server`; // 문서 내 스크립트 오류 방지를 위한 전역 함수들 정의 this.setupDocumentScriptHandlers(); console.log('✅ 문서 로드 완료:', docData.title); return docData; } catch (error) { console.error('Document load error:', error); // 백엔드 연결 실패시 목업 데이터로 폴백 console.warn('Using fallback mock data'); const mockDocument = { id: documentId, title: 'Document Server 테스트 문서', description: '하이라이트와 메모 기능을 테스트하기 위한 샘플 문서입니다.', uploader_name: '관리자' }; // 기본 HTML 내용 표시 document.getElementById('document-content').innerHTML = `
이 문서는 Document Server의 하이라이트 및 메모 기능을 테스트하기 위한 샘플입니다.
텍스트를 선택하면 하이라이트를 추가할 수 있습니다.
이것은 하이라이트 테스트를 위한 긴 단락입니다. 이 텍스트를 선택하여 하이라이트를 만들어보세요. 하이라이트를 만든 후에는 메모를 추가할 수 있습니다. 메모는 나중에 검색하고 편집할 수 있습니다.
또 다른 단락입니다. 여러 개의 하이라이트를 만들어서 메모 기능을 테스트해보세요. 각 하이라이트는 고유한 색상을 가질 수 있으며, 연결된 메모를 통해 중요한 정보를 기록할 수 있습니다.
`; // 폴백 모드에서도 스크립트 핸들러 설정 this.setupDocumentScriptHandlers(); return mockDocument; } } /** * 네비게이션 정보 로드 */ async loadNavigation(documentId) { try { // CachedAPI의 getDocumentNavigation 메서드 사용 const navigation = await this.api.getDocumentNavigation(documentId); console.log('📍 네비게이션 정보 로드됨:', navigation); return navigation; } catch (error) { console.error('❌ 네비게이션 정보 로드 실패:', error); return null; } } /** * URL 파라미터에서 특정 텍스트 하이라이트 확인 */ checkForTextHighlight() { const urlParams = new URLSearchParams(window.location.search); const highlightText = urlParams.get('highlight_text'); const startOffset = parseInt(urlParams.get('start_offset')); const endOffset = parseInt(urlParams.get('end_offset')); if (highlightText && !isNaN(startOffset) && !isNaN(endOffset)) { console.log('🎯 URL에서 하이라이트 요청:', { highlightText, startOffset, endOffset }); // 임시 하이라이트 적용 및 스크롤 setTimeout(() => { this.highlightAndScrollToText({ targetText: highlightText, startOffset: startOffset, endOffset: endOffset }); }, 500); // DOM 로딩 완료 후 실행 } } /** * 문서 내 스크립트 핸들러 설정 */ setupDocumentScriptHandlers() { // 업로드된 HTML 문서에서 사용할 수 있는 전역 함수들 정의 // 언어 토글 함수 (많은 문서에서 사용) window.toggleLanguage = function() { const koreanContent = document.getElementById('korean-content'); const englishContent = document.getElementById('english-content'); if (koreanContent && englishContent) { if (koreanContent.style.display === 'none') { koreanContent.style.display = 'block'; englishContent.style.display = 'none'; } else { koreanContent.style.display = 'none'; englishContent.style.display = 'block'; } } else { // 다른 언어 토글 방식들 const elements = document.querySelectorAll('[data-lang]'); elements.forEach(el => { if (el.dataset.lang === 'ko') { el.style.display = el.style.display === 'none' ? 'block' : 'none'; } else if (el.dataset.lang === 'en') { el.style.display = el.style.display === 'none' ? 'block' : 'none'; } }); } }; // 문서 인쇄 함수 window.printDocument = function() { // 현재 페이지의 헤더/푸터 숨기고 문서 내용만 인쇄 const originalTitle = document.title; const printContent = document.getElementById('document-content'); if (printContent) { const printWindow = window.open('', '_blank'); printWindow.document.write(`