diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 60a40c4..7e327f2 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -33,13 +33,13 @@
"message": "Set blur effect on Original Window when popup"
},
"enableContainerIdentify": {
- "message": "keep open in the same container as original page"
+ "message": "Keep open in the same container as original page"
},
"blurPx": {
- "message": "blur effect strengh: "
+ "message": "Blur effect strengh: "
},
"blurTime": {
- "message": "blur in specific seconds (s): "
+ "message": "Blur in specific seconds (s): "
},
"keySelection": {
"message": "Response when selected key is pressing (Please test to ensure it meets expectations.)"
@@ -48,10 +48,10 @@
"message": "Search provider"
},
"custom": {
- "message": "custom search url (use %s as selected text)"
+ "message": "Custom (use %s as selected text)"
},
"searchDisable": {
- "message": "Disable search in popup window"
+ "message": "Disable"
},
"noneKey": {
"message": "None"
diff --git a/_locales/es/messages.json b/_locales/es/messages.json
index efdbbfb..0ea9113 100644
--- a/_locales/es/messages.json
+++ b/_locales/es/messages.json
@@ -33,13 +33,13 @@
"message": "Aplicar efecto de desenfoque en la ventana original al abrir el popup"
},
"enableContainerIdentify": {
- "message": "mantener abierto en el mismo contenedor que la página original"
+ "message": "Mantener abierto en el mismo contenedor que la página original"
},
"blurPx": {
- "message": "intensidad del efecto de desenfoque: "
+ "message": "Intensidad del efecto de desenfoque: "
},
"blurTime": {
- "message": "desenfoque en segundos específicos (s): "
+ "message": "Desenfoque en segundos específicos (s): "
},
"keySelection": {
"message": "Respuesta cuando se presiona la tecla seleccionada (Por favor, prueba para asegurarte de que cumple con las expectativas.)"
diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json
index ca0916b..46b496c 100644
--- a/_locales/zh_CN/messages.json
+++ b/_locales/zh_CN/messages.json
@@ -48,7 +48,7 @@
"message": "搜索引擎"
},
"custom": {
- "message": "自定义"
+ "message": "自定义(选中文本:%s)"
},
"searchDisable": {
"message": "禁用"
diff --git a/background.js b/background.js
index fc5bfe6..9f0256d 100644
--- a/background.js
+++ b/background.js
@@ -85,6 +85,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
});
console.log('Current window:', currentWindow);
+
const userConfigs = await loadUserConfigs();
let { originWindowId } = userConfigs;
@@ -135,15 +136,25 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
sendResponse({ status: 'window focus handled' });
}
+ const zoomFactor = await new Promise((resolve, reject) => {
+ chrome.tabs.getZoom(sender.tab.id, (zoom) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else {
+ resolve(zoom);
+ }
+ });
+ });
+
await Promise.all([
- saveConfig('lastClientX', request.lastClientX),
- saveConfig('lastClientY', request.lastClientY),
- saveConfig('lastScreenTop', request.top),
- saveConfig('lastScreenLeft', request.left),
- saveConfig('lastScreenWidth', request.width),
- saveConfig('lastScreenHeight', request.height)
+ saveConfig('lastClientX', request.lastClientX * zoomFactor),
+ saveConfig('lastClientY', request.lastClientY * zoomFactor),
+ saveConfig('lastScreenTop', request.top * zoomFactor),
+ saveConfig('lastScreenLeft', request.left * zoomFactor),
+ saveConfig('lastScreenWidth', request.width * zoomFactor),
+ saveConfig('lastScreenHeight', request.height * zoomFactor)
]);
-
+
const { disabledUrls } = userConfigs;
if (isUrlDisabled(sender.tab.url, disabledUrls)) {
sendResponse({ status: 'url disabled' });
@@ -174,7 +185,7 @@ async function handleLinkInPopup(linkUrl, tab, currentWindow) {
const {
lastClientX, lastClientY, enableContainerIdentify,
popupHeight, popupWidth, tryOpenAtMousePosition,
- lastScreenTop, lastScreenLeft, lastScreenWidth, lastScreenHeight
+ lastScreenTop, lastScreenLeft, lastScreenWidth, lastScreenHeight, devicePixelRatio
} = userConfigs;
const height = parseInt(popupHeight, 10) || 800;
@@ -185,6 +196,15 @@ async function handleLinkInPopup(linkUrl, tab, currentWindow) {
dx = Math.max(lastScreenLeft, Math.min(dx, lastScreenLeft + lastScreenWidth - width));
dy = Math.max(lastScreenTop, Math.min(dy, lastScreenTop + lastScreenHeight - height));
+ console.log("tryOpenAtMousePosition: " + tryOpenAtMousePosition )
+ console.log("lastScreenLeft: " + lastScreenLeft )
+ console.log("lastScreenTop: " + lastScreenTop )
+ console.log("lastScreenWidth: " + lastScreenWidth)
+ console.log("lastScreenHeight: " + lastScreenHeight)
+ console.log("dx - dy : " + dx + "-" + dy)
+ console.log("devicePixelRatio: " + devicePixelRatio)
+
+
const createData = {
url: linkUrl,
type: 'popup',
diff --git a/content.js b/content.js
index fed34ca..2b8cc2d 100644
--- a/content.js
+++ b/content.js
@@ -17,16 +17,8 @@ const configs = {
async function loadUserConfigs() {
return new Promise(resolve => {
chrome.storage.local.get(Object.keys(configs), storedConfigs => {
- // Merge stored configurations with default configs, setting defaults for undefined keys
const mergedConfigs = { ...configs, ...storedConfigs };
-
- // Update the main configs object with merged configurations
Object.assign(configs, mergedConfigs);
-
- // Log the merged configurations (optional)
- // console.log('Loaded and merged user configurations:', configs);
-
- // Resolve with the merged configurations
resolve(mergedConfigs);
});
});
@@ -54,10 +46,16 @@ function removeListeners() {
function handleEvent(e) {
if (e.type === 'dragstart') {
handleDragStart(e);
- } else if (['dragover', 'drop', 'dragend', 'mouseup'].includes(e.type)) {
+
+ } else if (['dragover', 'drop', 'dragend'].includes(e.type)) {
preventEvent(e);
} else if (e.type === 'click') {
handleClick(e);
+ } else if (e.type === 'mouseup') {
+ if (e.target.tagName === 'A' && e.target.href) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ }
}
}
@@ -84,7 +82,8 @@ async function handleDragStart(e) {
}
if (e.target.tagName === 'A' || (selectionText && searchEngine !== 'None')) {
- preventEvent(e);
+ e.preventDefault();
+ e.stopImmediatePropagation();
if (blurEnabled) {
document.body.style.filter = `blur(${blurPx}px)`;
@@ -108,8 +107,9 @@ function handleClick(e) {
preventEvent(e);
isDragging = false;
}
+
}
-
+
function isUrlDisabled(url, disabledUrls) {
return disabledUrls.some(disabledUrl => {
if (disabledUrl.includes('*')) {
@@ -182,10 +182,10 @@ window.addEventListener('focus', async () => {
try {
document.body.style.filter = '';
const data = await loadUserConfigs(['closeWhenFocusedInitialWindow']);
- const message = data.closeWhenFocusedInitialWindow
+ const message = data.closeWhenFocusedInitialWindow
? { action: 'windowRegainedFocus', checkContextMenuItem: true }
: { checkContextMenuItem: true };
-
+
const response = await sendMessageToBackground(message);
console.log("Background script responded:", response);
} catch (error) {
diff --git a/manifest.json b/manifest.json
index 0551b24..35c2967 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
- "version": "0.0.20",
+ "version": "0.0.21",
"default_locale": "en",
"icons": {
"48": "icon.svg",
diff --git a/options/options.css b/options/options.css
index 3768589..a4b0d19 100644
--- a/options/options.css
+++ b/options/options.css
@@ -9,27 +9,32 @@
border-radius: 4px;
}
-input[type="text"], input[type="number"], textarea {
+input[type="text"],
+input[type="number"],
+textarea {
min-width: 40%;
margin-right: 4px;
}
textarea {
width: 100%;
- box-sizing: border-box; /* Ensure the textarea takes the full width */
+ box-sizing: border-box;
+ /* Ensure the textarea takes the full width */
margin-top: 5px;
padding: 5px;
font-size: 14px;
- resize: vertical; /* Allow vertical resize */
+ resize: vertical;
+ /* Allow vertical resize */
}
legend {
background-color: #0000007d;
color: #fff;
padding: 3px 6px;
- }
+}
+
- /* Dark Mode */
+/* Dark Mode */
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
@@ -49,7 +54,9 @@ legend {
border-radius: 4px;
}
- input[type="text"], input[type="number"], textarea {
+ input[type="text"],
+ input[type="number"],
+ textarea {
min-width: 40%;
margin-right: 4px;
background-color: #1e1e1e;
@@ -59,11 +66,13 @@ legend {
textarea {
width: 100%;
- box-sizing: border-box; /* Ensure the textarea takes the full width */
+ box-sizing: border-box;
+ /* Ensure the textarea takes the full width */
margin-top: 5px;
padding: 5px;
font-size: 14px;
- resize: vertical; /* Allow vertical resize */
+ resize: vertical;
+ /* Allow vertical resize */
background-color: #1e1e1e;
color: #e0e0e0;
border: 1px solid #333;
@@ -74,4 +83,4 @@ legend {
color: #e0e0e0;
padding: 3px 6px;
}
-}
+}
\ No newline at end of file
diff --git a/options/options.html b/options/options.html
index 0a0d3fe..4e76464 100644
--- a/options/options.html
+++ b/options/options.html
@@ -25,6 +25,7 @@
+
diff --git a/options/options.js b/options/options.js index 16be409..26cfcce 100644 --- a/options/options.js +++ b/options/options.js @@ -1,18 +1,45 @@ +const configs = { + 'closeWhenFocusedInitialWindow': true, + 'tryOpenAtMousePosition': false, + 'hideBrowserControls': true, + 'popupHeight': 800, + 'popupWidth': 1000, + 'searchEngine': 'https://www.google.com/search?q=%s', + 'disabledUrls': [], + 'enableContainerIdentify': true, + 'blurEnabled': true, + 'blurPx': 3, + 'blurTime': 1, + 'modifiedKey': 'None', + 'originWindowId': '' +}; + document.addEventListener("DOMContentLoaded", init); -async function init() { - const userConfigs = await loadUserConfigs(); - setupPage(userConfigs); +function init() { + loadUserConfigs(setupPage); } -function setupPage(userConfigs = {}) { +function setupPage(userConfigs) { + userConfigs = userConfigs || {}; + + // Elements to translate and set labels for const elementsToTranslate = [ - 'keySelection', 'searchEngineSelection', 'popupSettings', 'blurEffectSettings', 'blacklist' + { id: 'keySelection', messageId: 'keySelection' }, + { id: 'searchEngineSelection', messageId: 'searchEngineSelection' }, + { id: 'popupSettings', messageId: 'popupSettings' }, + { id: 'blurEffectSettings', messageId: 'blurEffectSettings' }, + { id: 'blacklist', messageId: 'blacklist' } ]; - elementsToTranslate.forEach(id => setTextContent(id, id)); - ['custom', 'searchDisable', 'noneKey'].forEach(id => setInputLabel(id, id)); + elementsToTranslate.forEach(({ id, messageId }) => setTextContent(id, messageId)); + + // Set specific labels + setInputLabel('custom', 'custom'); + setInputLabel('searchDisable', 'searchDisable'); + setInputLabel('noneKey', 'noneKey'); + // Initialize input elements Object.keys(configs).forEach(key => { const input = document.getElementById(key); if (input) { @@ -21,18 +48,20 @@ function setupPage(userConfigs = {}) { } }); + // Initialize textarea and sliders initializeTextarea('disabledUrls', userConfigs); - initializeSlider('blurPx', userConfigs.blurPx ?? 3); - initializeSlider('blurTime', userConfigs.blurTime ?? 1); + initializeSlider('blurPx', 3); + initializeSlider('blurTime', 1); + + // Set modified key setModifiedKey(userConfigs.modifiedKey); + + // Setup search engine selection setupSearchEngineSelection(userConfigs.searchEngine); } function setTextContent(elementId, messageId) { - const element = document.getElementById(elementId); - if (element) { - element.textContent = chrome.i18n.getMessage(messageId); - } + document.getElementById(elementId).textContent = chrome.i18n.getMessage(messageId); } function setInputLabel(inputId, messageId) { @@ -63,8 +92,8 @@ function createLabel(input, key) { function addInputListener(input, key) { input.addEventListener("input", () => { - const value = input.type === 'checkbox' ? input.checked : input.value; - saveSingleSetting(key, value); + configs[key] = input.type === 'checkbox' ? input.checked : input.value; + saveAllSettings(); }); } @@ -73,8 +102,8 @@ function initializeTextarea(textareaId, userConfigs) { if (textarea) { textarea.value = (userConfigs[textareaId] ?? configs[textareaId]).join('\n'); textarea.addEventListener('input', () => { - const value = textarea.value.split('\n').filter(line => line.trim()); - saveSingleSetting(textareaId, value); + configs[textareaId] = textarea.value.split('\n').filter(line => line.trim()); + saveAllSettings(); }); } } @@ -88,95 +117,86 @@ function initializeSlider(id, defaultValue) { output.textContent = initialValue; input.addEventListener('input', () => { - const value = input.value; - output.textContent = value; - localStorage.setItem(id, value); - saveSingleSetting(id, value); + output.textContent = input.value; + localStorage.setItem(id, input.value); }); } -function setModifiedKey(modifiedKey = 'noneKey') { - const modifiedKeyInput = document.querySelector(`input[name="modifiedKey"][value="${modifiedKey}"]`); - if (modifiedKeyInput) { - modifiedKeyInput.checked = true; - } +function setModifiedKey(modifiedKey) { + modifiedKey = modifiedKey ?? 'None'; + document.querySelector(`input[name="modifiedKey"][value="${modifiedKey}"]`).checked = true; document.querySelectorAll('input[name="modifiedKey"]').forEach(input => { input.addEventListener('change', event => { - saveSingleSetting('modifiedKey', event.target.value); + chrome.storage.local.set({ modifiedKey: event.target.value }); }); }); } function setupSearchEngineSelection(searchEngine) { const customInput = document.getElementById('customSearchEngine'); - const searchEngines = ['google', 'bing', 'baidu', 'yandex', 'wiki', 'duckduckgo', 'custom', 'searchDisable']; + const searchEngines = ['google', 'bing', 'baidu', 'duckduckgo', 'custom', 'searchDisable', 'wiki', 'yandex']; + // Ensure the custom input event listener is set up properly customInput.addEventListener('input', () => { - saveSingleSetting('searchEngine', customInput.value); + chrome.storage.local.set({ searchEngine: customInput.value }); }); searchEngines.forEach(engine => { const radio = document.getElementById(engine); radio.addEventListener('change', () => { if (radio.checked) { - const searchEngineValue = engine === 'custom' ? customInput.value : radio.value; - customInput.style.display = engine === 'custom' ? 'block' : 'none'; - saveSingleSetting('searchEngine', searchEngineValue); + let searchEngineValue; + if (engine === 'custom') { + customInput.style.display = 'block'; + searchEngineValue = customInput.value; + } else { + customInput.style.display = 'none'; + searchEngineValue = radio.value; + } + chrome.storage.local.set({ searchEngine: searchEngineValue }); } }); + // Restore saved value on load if (searchEngine === radio.value) { radio.checked = true; customInput.style.display = engine === 'custom' ? 'block' : 'none'; } }); + // Special handling for initial load if 'custom' is selected if (!searchEngines.some(engine => searchEngine === document.getElementById(engine)?.value)) { const customRadio = document.getElementById('custom'); - if (customRadio) { - customRadio.checked = true; - customInput.style.display = 'block'; - customInput.value = searchEngine; - } + customRadio.checked = true; + customInput.style.display = 'block'; + customInput.value = searchEngine; } } -async function loadUserConfigs() { +function loadUserConfigs(callback) { const keys = Object.keys(configs); - return new Promise(resolve => { - chrome.storage.local.get(keys, userConfigs => { - Object.keys(configs).forEach(key => { - if (userConfigs[key] === undefined) { - userConfigs[key] = configs[key]; - } - }); - resolve(userConfigs); + chrome.storage.local.get(keys, function (userConfigs) { + userConfigs.searchEngine = userConfigs.searchEngine ?? configs.searchEngine; + userConfigs.modifiedKey = userConfigs.modifiedKey ?? configs.modifiedKey; + + keys.forEach(key => { + if (userConfigs[key] !== null && userConfigs[key] !== undefined) { + configs[key] = userConfigs[key]; + } }); - }); -} -function saveAllSettings() { - debounce(() => { - chrome.storage.local.set(configs); - }, 300)(); + if (callback) callback(userConfigs); + }); } -function saveSingleSetting(key, value) { +function saveConfig(key, value) { configs[key] = value; - debounce(() => { - chrome.storage.local.set({ [key]: value }); - }, 300)(); + let data = {}; + data[key] = value; + chrome.storage.local.set(data); } -function debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; -} +function saveAllSettings() { + chrome.storage.local.set(configs); +} \ No newline at end of file