-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontentScript.js
More file actions
230 lines (193 loc) · 9.19 KB
/
Copy pathcontentScript.js
File metadata and controls
230 lines (193 loc) · 9.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
(() => {
// 스크립트 중복 실행 방지 및 오버레이 참조 변수
if (window.naverMapRandomClickExecuting) {
console.log("이미 랜덤 우클릭 스크립트가 실행 중입니다.");
return;
}
window.naverMapRandomClickExecuting = true; // 실행 중 플래그 설정
const overlayId = 'naverMapRandomClickOverlay'; // 오버레이 식별 ID
const pinImageId = 'naverMapRandomClickPin'; // 핀 이미지 식별 ID
// 상수 정의
const MAX_BUTTON_FIND_ATTEMPTS = 50; // 버튼 검색 최대 시도 횟수
const BUTTON_RETRY_INTERVAL_MS = 10; // 버튼 검색 재시도 간격 (밀리초)
const BUTTON_SEARCH_DELAY_MS = 100; // 우클릭 후 버튼 검색 시작 대기 시간 (밀리초)
const PIN_IMAGE_WIDTH_PX = 32; // 핀 이미지 너비 (픽셀)
const DEFAULT_PIN_HEIGHT_PX = 32; // 핀 이미지 기본 높이 (픽셀)
console.log("네이버 지도 랜덤 우클릭 스크립트 시작 (v4 - 보이는 지도 중앙 정렬).");
// 이전 오버레이 및 핀 이미지 제거 (있다면)
const existingOverlay = document.getElementById(overlayId);
if (existingOverlay) {
existingOverlay.remove();
}
const existingPin = document.getElementById(pinImageId);
if (existingPin) {
existingPin.remove();
}
// 이전 클릭 리스너 제거 (안전장치)
if (window.removeNaverMapOverlayOnClick) {
document.removeEventListener('click', window.removeNaverMapOverlayOnClick, true);
window.removeNaverMapOverlayOnClick = null;
}
const canvasSelector = "canvas";
const canvas = document.querySelector(canvasSelector);
if (!canvas) {
console.error("네이버 지도 캔버스를 찾을 수 없습니다.");
alert("네이버 지도 캔버스를 찾을 수 없습니다.");
delete window.naverMapRandomClickExecuting;
return;
}
const rect = canvas.getBoundingClientRect();
const canvasWidth = Math.max(0, rect.width);
const canvasHeight = Math.max(0, rect.height);
if (canvasHeight <= 0) {
console.error("캔버스 높이가 유효하지 않습니다.");
delete window.naverMapRandomClickExecuting;
return;
}
// --- 1. 보이는 지도 영역 계산 및 중앙 사각형 오버레이 생성 ---
// 왼쪽 패널 너비 계산 (패널이 없을 수도 있음을 고려)
const leftPanelSelector = "#app-layout > div.sc-wli0gr.bNZoFo > div > div.sc-1wsjitl.jjlEdZ"; // 왼쪽 패널 선택자 (사용자 제공)
const leftPanel = document.querySelector(leftPanelSelector);
let leftPanelWidth = 0;
if (leftPanel && getComputedStyle(leftPanel).display !== 'none') {
leftPanelWidth = leftPanel.getBoundingClientRect().width;
}
console.log(`왼쪽 패널 너비 추정: ${leftPanelWidth.toFixed(0)}px`);
const visibleMapWidth = canvasWidth - leftPanelWidth;
const squareSize = Math.min(visibleMapWidth, canvasHeight); // 너비와 높이 중 작은 값으로 정사각형 크기 결정 (화면 왜곡 방지)
// 정사각형 위치 계산 (보이는 지도 영역 기준 중앙)
const squareTop = rect.top + (canvasHeight - squareSize) / 2; // 세로 중앙
const squareLeft = rect.left + leftPanelWidth + (visibleMapWidth - squareSize) / 2; // 가로 중앙
const overlay = document.createElement('div');
overlay.id = overlayId;
overlay.style.position = 'absolute';
overlay.style.top = `${squareTop}px`;
overlay.style.left = `${squareLeft}px`;
overlay.style.width = `${squareSize}px`;
overlay.style.height = `${squareSize}px`;
overlay.style.border = '2px dashed rgba(255, 0, 0, 0.7)'; // 빨간 점선 테두리만
// overlay.style.backgroundColor = 'rgba(255, 0, 0, 0.05)'; // 배경색 제거
overlay.style.zIndex = '10000';
overlay.style.pointerEvents = 'none';
document.body.appendChild(overlay);
console.log(`중앙 사각형 표시 (보이는 지도 기준): top=${squareTop.toFixed(0)}, left=${squareLeft.toFixed(0)}, size=${squareSize.toFixed(0)}`);
// --- 2. 랜덤 좌표를 사각형 내부로 제한 ---
// 사각형 내부의 랜덤 좌표 생성 (사각형 기준 0 ~ size)
const randomXInSquare = Math.random() * squareSize;
const randomYInSquare = Math.random() * squareSize;
// 화면(Viewport) 기준 좌표 계산
const clientX = squareLeft + randomXInSquare;
const clientY = squareTop + randomYInSquare;
console.log(`캔버스 크기: ${canvasWidth.toFixed(0)}x${canvasHeight.toFixed(0)}`);
console.log(`보이는 지도 너비 추정: ${visibleMapWidth.toFixed(0)}px`);
console.log(`사각형 내부 랜덤 좌표 (사각형 기준): (${randomXInSquare.toFixed(2)}, ${randomYInSquare.toFixed(2)})`);
console.log(`뷰포트 기준 클릭 좌표 (Client): (${clientX.toFixed(2)}, ${clientY.toFixed(2)})`);
// --- 3. 이벤트 발생 ---
const commonEventOptions = {
bubbles: true,
cancelable: true,
view: window,
button: 2,
buttons: 2,
clientX: clientX,
clientY: clientY
};
const mouseDownEvent = new MouseEvent('mousedown', commonEventOptions);
canvas.dispatchEvent(mouseDownEvent);
const mouseUpEvent = new MouseEvent('mouseup', commonEventOptions);
canvas.dispatchEvent(mouseUpEvent);
const contextMenuEvent = new MouseEvent('contextmenu', commonEventOptions);
try {
canvas.dispatchEvent(contextMenuEvent);
console.log(`랜덤 좌표(${clientX.toFixed(0)}, ${clientY.toFixed(0)})에 이벤트 발생 완료.`);
if (contextMenuEvent.defaultPrevented) {
console.log("기본 contextmenu 동작 방지됨.");
} else {
console.warn("기본 contextmenu 동작 방지 안됨.");
}
// --- btn_address 버튼 자동 클릭 ---
setTimeout(() => {
console.log("btn_address 버튼 검색 시작...");
let attempts = 0;
const findAndClickButton = () => {
attempts++;
const btnAddress = document.querySelector('.btn_address');
if (btnAddress) {
console.log(`btn_address 버튼 발견 (시도 ${attempts}번째)`);
btnAddress.click();
console.log("btn_address 버튼 클릭 완료");
return;
}
if (attempts < MAX_BUTTON_FIND_ATTEMPTS) {
setTimeout(findAndClickButton, BUTTON_RETRY_INTERVAL_MS);
} else {
console.warn("btn_address 버튼을 찾지 못했습니다 (타임아웃)");
}
};
findAndClickButton();
}, BUTTON_SEARCH_DELAY_MS);
} catch (error) {
console.error("이벤트 발생 중 오류:", error);
alert("지도에 이벤트를 발생시키는 중 오류가 발생했습니다.");
}
// --- 4. 핀 이미지 표시 ---
const pinImage = document.createElement('img');
pinImage.id = pinImageId;
pinImage.src = chrome.runtime.getURL('assets/pin.png');
pinImage.style.position = 'absolute';
pinImage.style.zIndex = '10001'; // 오버레이보다 위에 표시
pinImage.style.pointerEvents = 'none';
pinImage.style.width = `${PIN_IMAGE_WIDTH_PX}px`;
pinImage.style.height = 'auto';
// 이미지 로드 완료 후 위치 설정
pinImage.onload = () => {
const pinWidth = pinImage.offsetWidth;
const pinHeight = pinImage.offsetHeight;
// 좌측 하단 꼭짓점을 클릭 지점에 맞춤
pinImage.style.left = `${clientX}px`;
pinImage.style.top = `${clientY - pinHeight}px`;
console.log(`핀 이미지 표시: 크기=${pinWidth}x${pinHeight}, 위치=(${clientX}, ${clientY - pinHeight})`);
};
// 이미지 로드 실패 시 기본 위치 설정
pinImage.onerror = () => {
console.warn("핀 이미지 로드 실패, 기본 크기로 설정");
pinImage.style.left = `${clientX}px`;
pinImage.style.top = `${clientY - DEFAULT_PIN_HEIGHT_PX}px`;
};
document.body.appendChild(pinImage);
// --- 5. 오버레이 제거를 위한 클릭 리스너 추가 ---
window.removeNaverMapOverlayOnClick = (event) => {
// btn_address 버튼 클릭인지 확인 (버튼 클릭 시 오버레이 유지)
if (event.target.closest('.btn_address')) {
console.log("btn_address 버튼 클릭 감지됨. 오버레이 및 핀 이미지 유지.");
return;
}
const overlayElement = document.getElementById(overlayId);
const pinElement = document.getElementById(pinImageId);
if (!overlayElement && !pinElement) {
document.removeEventListener('click', window.removeNaverMapOverlayOnClick, true);
window.removeNaverMapOverlayOnClick = null;
return;
}
let clickOutsideOverlay = true;
if (overlayElement) {
const overlayRect = overlayElement.getBoundingClientRect();
if (event.clientX >= overlayRect.left && event.clientX <= overlayRect.right &&
event.clientY >= overlayRect.top && event.clientY <= overlayRect.bottom) {
clickOutsideOverlay = false;
}
}
if (clickOutsideOverlay) {
console.log("오버레이 외부 클릭 감지됨. 오버레이 및 핀 이미지 제거.");
if (overlayElement) overlayElement.remove();
if (pinElement) pinElement.remove();
document.removeEventListener('click', window.removeNaverMapOverlayOnClick, true);
window.removeNaverMapOverlayOnClick = null;
}
};
document.addEventListener('click', window.removeNaverMapOverlayOnClick, true);
// 스크립트 실행 완료 후 플래그 해제
setTimeout(() => {
delete window.naverMapRandomClickExecuting;
}, 0);
})();