In chrome documentation, we can send message from option page by using:
chrome.runtime.sendMessage
We cannot use:
chrome.tabs.sendMessage
I want to send message from option page to content script. Can I do it directly?
This is my option page script:
document.addEventListener("DOMContentLoaded", function() {
var radio = document.querySelectorAll("input[type=radio][name=quality]");
for(i=0; i<radio.length; i++)
radio[i].addEventListener("change", function(){
val = this.id;
localStorage.setItem("youtube_filter_video_quality", val);
chrome.runtime.sendMessage({"youtube_filter_video_quality": val});
});
});
And here is content script:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if(request.youtube_filter_video_quality!==undefined){
console.log(request.youtube_filter_video_quality);
}
}
);
And here is manifest.json:
{
"name": "__MSG_name__",
"short_name": "__MSG_short_name__",
"manifest_version": 2,
"version":"1.5.0.0",
"description": "__MSG_description__",
"default_locale": "en",
"browser_action": {
"default_icon": "48.png",
"default_title": "__MSG_default_title__",
"default_popup": "popup.html"
},
"background":{
"page":"background.html",
"persistent": false
},
"content_scripts":[
{
"matches": [ "*://*.youtube.com/*" ],
"css": ["app_player.css"],
"run_at": "document_end"
}
],
"permissions": [
"tabs",
"activeTab",
"storage",
"<all_urls>",
"webNavigation"
],
"icons": {
"64":"64.png",
"48": "48.png",
"32":"32.png",
"16": "16.png",
"128": "128.png"
},
"options_page": "options.html",
"options_ui": {
"chrome_style": true,
"page": "option.html"
}
}
The console.log cannot write anything (blank).
Related
My Chrome extension mv3 receives messages from webpage and replies to it. Here are the codes in webpage to send message to extension:
chrome.runtime.sendMessage(chromeExtensionId,
{
"Message": "Hello",
"Data":
{
"Name": 'Jason'
}
},
function(response) {
console.log("chrome.runtime.sendMessage", response);
});
and codes in extension's background.js to receive message and reply with true/false:
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
console.log(message, sender));
sendResponse(true);
});
manifest.json:
{
"background": {
"service_worker": "background.js"
},
"action": {
"default_icon": {
"16": "images/logo16.png",
"32": "images/logo32.png"
},
"default_title": "My Extension"
},
"content_scripts": [ {
"all_frames": true,
"match_about_blank": true,
"js": [ "util.js", "contentscript.js" ],
"matches": [ "http://*/*", "https://*/*" ],
"run_at": "document_end"
} ],
"description": " ",
"externally_connectable": {
"matches": [ "https://*.mysite.com/*", "http://*.mysite.com/*" ]
},
"icons": {
"128": "/images/logo128.png",
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png"
},
"manifest_version": 3,
"name": "My Extension",
"permissions": ["cookies", "tabs", "proxy", "alarms", "storage", "downloads", "webRequest", "notifications", "nativeMessaging", "clipboardRead", "clipboardWrite", "declarativeNetRequest","declarativeNetRequestFeedback" ],
"host_permissions": ["<all_urls>"],
"version": "4.0.7"
}
Most of the time it works fine.
The only problem is when i set my webpage as startup page of chrome, which means the page is opened immediately when chrome starts, sendMessage does not return and console.log in both sender and receiver sides are not printed. There is no error output in console either. It looks like codes freeze inside sendMessage. What's going on there?
It's a known problem. Chrome intentionally delays extensions at browser startup to show the active tab faster. The workaround is to repeat sendMessage:
send('abcdefgkhgghfg........', {foo: 'bar'}, res => {
console.log('response', res);
});
function send(extensionId, msg, callback, retry = 20) {
const timer = setTimeout(send, 100, extensionId, msg, callback, retry - 1);
chrome.runtime.sendMessage(extensionId, msg, response => {
if (!chrome.runtime.lastError || !retry) {
clearTimeout(timer);
callback(response);
}
});
}
Manifest.json
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"32": "icons/32x32.png"
}
},
"content_scripts": [
{
"matches": ["*://*/*"],
"run_at": "document_start",
"js": ["content-script.js"]
}
],
"permissions": [
"scripting",
"tabs",
"notifications",
"activeTab",
"webRequest"
],
"host_permissions": ["*://*/*", "https://*/*"],
"web_accessible_resources": [
{
"matches": ["*://*/*", "http://*/*", "https://*/*"],
"resources": ["web.js"]
}
],
"icons": {
"32": "/icons/32x32.png"
}
}
content-script.js
console.log("I am content script");
function injectScript() {
var script = document.createElement("script");
script.src = chrome.runtime.getURL("scripts/web.js");
script.type = "text/javascript";
console.log("Inserting Script", document);
document.head.appendChild(script);
}
injectScript();
web.js
console.log("I am web.js");
setInterval(() => {
console.log(window.test, "Test in setInterval");
}, 1000);
console.log(window.test, "Logging test from web.js");
// document.body.style.backgroundColor = "red";
Upon refreshing the page I am getting the following error
Not able to get what could be the issue, can someone guide me?
Thank You!
I am trying to block all drop event via content script in chrome extension. However, the code is getting executed as I can get console.log output, but drop of file is not prevented.
inject.js file:
console.log("worked?");
document.addEventListener("ondrop", function(event){
event.preventDefault();
}, false)
document.addEventListener("dragstart", function(event){
event.preventDefault();
}, true);
document.addEventListener("dragenter", function(event){
event.preventDefault();
}, true);
document.addEventListener("dragleave", function(event){
event.preventDefault();
}, true);
document.addEventListener("drag", function(event){
event.preventDefault();
}, true);
manifest.json file:
{
"name": "BlockDrop",
"version": "0.0.1",
"manifest_version": 2,
"description": "Block dropping of files .",
"homepage_url": "http://sample.com?explode_chrome",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_locale": "en",
"background": {
"scripts": [
"src/bg/background.js"
],
"persistent": true
},
"browser_action": {
"default_icon": "icons/icon19.png",
"default_title": "browser action demo",
"default_popup": "src/browser_action/browser_action.html"
},
"permissions": [
"clipboardRead",
"clipboardWrite",
"cookies",
"https://*/*",
"http://*/*"
],
"content_scripts": [
{
"matches": [
"https://*/*",
"http://*/*"
],
"js": [
"src/inject/inject.js"
],
"run_at" : "document_idle"
}
]
}
I need to find the id of the element that holds text that I've selected, and I've been unsuccessful at finding a way to do this. It looks like the problem is with the fact that you can't use a getAttribute method on a window object. I am using a content script that communicates with an event page to carry it out. This is my content script:
let element = window.getSelection().anchorNode;
let finder = element.getAttribute('id');
alert(finder.toString()); //test
This is my event page:
chrome.contextMenus.create({ id: "M", title: "Feature One", contexts: ["selection"] });
chrome.contextMenus.create({ id: "ATCB", title: "Feature Two", contexts: ["selection"] });
chrome.contextMenus.onClicked.addListener(function(clickData){
if (clickData.menuItemId == "M" && clickData.selectionText){
//var one = clickData.selectionText;
chrome.tabs.executeScript({
file: 'contentScript.js'
});
}
if (clickData.menuItemId == "ATCB" && clickData.selectionText){
var two = clickData.selectionText;
alert(two + " two"); //test
}
});
And this is my manifest file:
{
"manifest_version": 2,
"name": "Menu",
"version": "1.0",
"icons": {
"128": "icon.png",
"48": "icon.png",
"16": "icon.png"
},
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["eventPage.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["contentScript.js"]
}],
"permissions": [
"contextMenus",
"tabs",
"activeTab",
"file://*/*",
"https://*/*",
"http://*/*"
]
}
Thank you for reading my question
This can be accomplished with document.activeElement.id;
https://www.w3schools.com/jsref/prop_document_activeelement.asp
I am trying to learn about chrome extensions but I am not able to understand how to manipulate DOM of a page using content_scripts.
manifest.json
{
"name": "First",
"version": "1.0",
"manifest_version": 2,
"description": "First extension",
"background": {
"scripts": ["test.js"]
},
"page_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [ {
"js": [ "jquery.min.js", "popup1.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"permissions" : [
"tabs",
"http://*/*"
]
}
test.js
function check(tab_id, data, tab){
if(tab.url.indexOf("google") > -1){
chrome.pageAction.show(tab_id);
}
};
chrome.tabs.onUpdated.addListener(check);
popup1.js
function myfunc(){
var x = $('#options option:selected').text();
$("body").append('Test');
alert(x);
//window.close();
}
$(document).ready(function(){
$('#options').change(myfunc);
});
The above code/extension works fine because myfunc gets called but it doesn't inject Test into the body of google.com.
So, where am I going wrong in accessing/manipulating the DOM.
If you want to play with browser tab DOM on event of popup. In this case you have to pass a message to content script from background script, or inject JavaScript into content script : have a look
manifest.json
{
"name": "First",
"version": "1.0",
"manifest_version": 2,
"description": "First extension",
"background": {
"scripts": ["test.js"]
},
"page_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [ {
"js": [ "jquery.min.js", "content_script.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"permissions" : [
"tabs",
"http://*/*"
]
}
content_script.js
function myfunc(){
var x = $('#options option:selected').text();
$("body").append('<div style="width:200px; height:200px; border: 1px solid red;"></div>');
}
$(document).ready(myfunc);
Now you will get A box with red border at the bottom of the page.
popup.js
function myfunc(){
var x = $('#options option:selected').text();
chrome.extension.sendMessage({sel_text: x});
}
$(document).ready(function(){
$('#options').change(myfunc);
});
test.js (used in background)
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
appendTextToBody(request.sel_text);
});
function appendTextToBody(text) {
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.executeScript(tab.id, {"code" : '$("body").append("Test : "'+text+');'}) ;
});
}
function check(tab_id, data, tab){
if(tab.url.indexOf("google") > -1){
chrome.pageAction.show(tab_id);
}
};
chrome.tabs.onUpdated.addListener(check);