Chrome Extension MV3에서 commands를 선별적으로 활성화 할 수 있을까?
DoDoBest
·2023. 4. 10. 22:19
결론: 현재로서는 불가능합니다.
네이버 카페에서 특정 등급이나 등록한 사용자의 게시물을 숨기는 확장 프로그램입니다. 네이버 카페는 InnerFrame에서 게시물을 보여주기 때문에, 관심있는 판매글을 북마크하려면 판매글의 주소를 직접 복사해서 등록해야 합니다. 이 과정을 단축키로 수행할 수 있도록 기능을 추가했습니다.
그러나 Ctrl+B와 같은 단축키가 다른 사이트에서 이미 설정되어 있을 경우, 해당 사이트의 단축키가 동작하지 않는 문제가 발생합니다.
따라서, 네이버 카페가 아닌 곳에서 단축키를 입력할 경우, 북마크 기능 대신 해당 사이트의 단축키를 동작하도록 수정해야 합니다. 이를 위해 자바스크립트 코드로 입력된 단축키와 동일한 효과를 주는 방식을 생각해보았습니다.
1. dispatchEvent 활용하기
아래는 구현한 코드입니다. 코드는 에러 없이 정상적으로 실행되지만, 키보드 입력 효과가 나타나지는 않았습니다.
function handleShortCut(shortCut) {
function parseShortcut(shortcutString) {
const parts = shortcutString.split('+');
return {
key: parts.pop().toUpperCase(),
ctrlKey: parts.includes('Ctrl'),
shiftKey: parts.includes('Shift'),
altKey: parts.includes('Alt'),
metaKey: parts.includes('Cmd') || parts.includes('Meta'),
};
}
const { key, ctrlKey, shiftKey, altKey, metaKey } = parseShortcut(shortCut);
document.dispatchEvent(
new KeyboardEvent('keydown', {
key,
ctrlKey,
shiftKey,
altKey,
metaKey,
})
);
}
chrome.commands.onCommand.addListener((command) => {
if (command.toString() === 'add-bookmark') {
addBookMark(null, true).then(function (result) {
if (result !== false) {
return;
}
chrome.commands.getAll((commands) => {
const commandKey = commands.find((cmd) => cmd.name === command.toString())?.shortcut;
if (!commandKey) {
return;
}
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
// 1. document.dispatchEvent
chrome.scripting.executeScript({
target: {tabId: tabs[0].id, frameIds: [0]},
func: handleShortCut,
args: [commandKey],
});
});
});
});
}
});
관련 참고 자료
2. chrome.debugger
https://stackoverflow.com/a/34722970
위 답변을 참고하여, chrome.debugger를 사용하여 아래와 같이 코드를 구현하였습니다. 그러나 이 코드도 아무런 효과가 나타나지 않았습니다. 만약 효과가 있다고 하더라도, 디버깅 중임을 나타내는 상단 안내창이 뜨고 몇 초의 시간이 소요되어사용하기 어려울 것 같습니다. 빠른 확인을 위해 Ctrl+B를 하드코딩하여 동작하도록 설정했습니다.
chrome.commands.onCommand.addListener((command) => {
if (command.toString() === 'add-bookmark') {
addBookMark(null, true).then(function (result) {
if (result !== false) {
return;
}
chrome.commands.getAll((commands) => {
const commandKey = commands.find((cmd) => cmd.name === command.toString())?.shortcut;
if (!commandKey) {
return;
}
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.debugger.attach({ tabId: tabs[0].id }, "1.0").then(function() {
chrome.debugger.sendCommand({tabId: tabs[0].id}, 'Input.dispatchKeyEvent', {
type: 'rawKeyDown',
windowsVirtualKeyCode: 0x11,
nativeVirtualKeyCode: 0x11,
}).then(function() {
chrome.debugger.sendCommand({tabId: tabs[0].id}, 'Input.dispatchKeyEvent', {
type: 'rawKeyDown',
windowsVirtualKeyCode: 0x42,
nativeVirtualKeyCode: 0x42,
}).then(function() {
chrome.debugger.detach({ tabId: tabs[0].id });
});
});
})
});
});
});
}
});
chrome.debugger의 arguments 관련 정보
https://chromedevtools.github.io/devtools-protocol/tot/Input/
windowVirtualKeyCode 정보
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
ChatGPT 답변
GPT 3.5와 GPT 4.0 모두 1번 dispatchEvent 함수를 사용하는 방법을 알려줬습니다. GPT 3.5는 알려준 방법이 작동하지 않는 다는 질문에 약간 다른 코드를 계속 알려주다가 마지막에는 2개의 답변을 번갈아가며 알려줬습니다.
하지만 GPT 4.0에서는 안 된다는 계속된 질문에 아래와 같이 답변했습니다.
'ChatGPT와 학습하기' 카테고리의 다른 글
HashTable과 HashMap (0) | 2023.03.06 |
---|---|
ArrayList와 LinkedList (0) | 2023.02.20 |