Last active
December 18, 2024 10:47
-
-
Save lunamoth/6836fa2912be1424b172d704c6bee846 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 웹페이지 제목/URL 복사 스크립트 | |
// @namespace http://tampermonkey.net/ | |
// @version 2.8 | |
// @description Alt+1 키를 눌러 현재 페이지의 제목과 URL을, Alt+Q 키를 눌러 URL만 클립보드에 복사합니다. | |
// @author Claude & Gemini | |
// @match *://*/* | |
// @grant GM_setClipboard | |
// @grant GM_addStyle | |
// ==/UserScript== | |
(() => { | |
'use strict'; | |
const CONFIG = { | |
KEY_TITLE_URL: '1', | |
KEY_URL_ONLY: 'q', | |
POPUP_DURATION_MS: 2000, | |
POPUP_MESSAGE: '복사 완료', | |
TITLE_URL_SEPARATOR: '\n\n', // 제목과 URL 사이 구분자 | |
POPUP_TOP: '20px', // 팝업 상단 위치 | |
POPUP_LEFT: '50%', // 팝업 좌측 위치 | |
POPUP_TRANSFORM: 'translateX(-50%)', // 팝업 가로축 이동 | |
POPUP_BACKGROUND_COLOR: '#22A06B', // 팝업 배경색 | |
POPUP_TEXT_COLOR: '#fff', // 팝업 텍스트 색상 | |
POPUP_PADDING: '10px 20px', // 팝업 패딩 | |
POPUP_BORDER_RADIUS: '5px', // 팝업 테두리 반경 | |
POPUP_Z_INDEX: 9999, // 팝업 z-index | |
}; | |
// 팝업 요소 생성 (한 번만 생성) | |
const style = ` | |
.copy-popup { | |
position: fixed; | |
top: ${CONFIG.POPUP_TOP}; | |
left: ${CONFIG.POPUP_LEFT}; | |
transform: ${CONFIG.POPUP_TRANSFORM}; | |
background-color: ${CONFIG.POPUP_BACKGROUND_COLOR}; | |
color: ${CONFIG.POPUP_TEXT_COLOR}; | |
padding: ${CONFIG.POPUP_PADDING}; | |
border-radius: ${CONFIG.POPUP_BORDER_RADIUS}; | |
z-index: ${CONFIG.POPUP_Z_INDEX}; | |
display: none; | |
} | |
`; | |
GM_addStyle(style); | |
const popup = document.createElement('div'); | |
popup.className = 'copy-popup'; | |
popup.textContent = CONFIG.POPUP_MESSAGE; | |
document.body.appendChild(popup); | |
// DOM 접근 최소화를 위한 변수 | |
let pageTitle = document.title; | |
let pageURL = window.location.href; | |
// MutationObserver를 사용하여 document.title 변경 감지 | |
const titleObserver = new MutationObserver((mutations) => { | |
mutations.forEach((mutation) => { | |
if (mutation.type === 'childList' && mutation.target === document.querySelector('title')) { | |
pageTitle = document.title; | |
} | |
}); | |
}); | |
titleObserver.observe(document.querySelector('title'), { childList: true }); | |
// 팝업 표시 함수 | |
const showPopup = () => { | |
popup.style.display = 'block'; | |
setTimeout(() => { | |
popup.style.display = 'none'; | |
}, CONFIG.POPUP_DURATION_MS); | |
}; | |
// 클립보드 복사 함수 (비동기 처리 개선) | |
const copyToClipboard = (content) => { | |
// GM_setClipboard가 Promise를 반환하는지 확인 (Tampermonkey API 문서 확인 필요) | |
const result = GM_setClipboard(content); | |
if (result instanceof Promise) { | |
result.then(() => { | |
showPopup(); | |
}); | |
} else { | |
showPopup(); | |
} | |
}; | |
// 웹페이지 정보 (제목 + URL) 복사 함수 | |
const copyWebpageInfo = () => { | |
const content = pageTitle + CONFIG.TITLE_URL_SEPARATOR + pageURL; | |
copyToClipboard(content); | |
}; | |
// 웹페이지 URL만 복사 함수 | |
const copyWebpageUrl = () => { | |
copyToClipboard(pageURL); | |
}; | |
// 키 입력 처리 함수 (이벤트 리스너 최적화) | |
document.addEventListener('keydown', (e) => { | |
if (e.altKey) { | |
if (e.key === CONFIG.KEY_TITLE_URL) { | |
copyWebpageInfo(); | |
} else if (e.key === CONFIG.KEY_URL_ONLY) { | |
copyWebpageUrl(); | |
} | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment