Looking to squeeze in the CSS for Bootstrap's Popover somewhere in my Chrome Extension. That's literally all I need to do. Include the CSS for a library so my popover (tooltip) is styled.
So far I've tried InsertCSS() in the background page, and adding a stylesheet element appended to the head which kept throwing an error requiring it to be listed on "web_accessible_resources" which it was. Spelling was all correct too.
My code:
NOTE The content_script file is included for posterity. I don't think it's valuable here, but ymmv. Way too long, but It's there. Yes there is a frame on the page I'm editing.
Manifest.json
{
"name": "RMP",
"description": "Work in Progress",
"manifest_version": 2,
"version": "0.8",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"activeTab",
"http://*/",
"https://*/"
],
"background": {
"scripts": ["jquery-3.2.1.min.js","bootstrap.min.js","background.js"],
"persistent": false
},
"browser_action": {
"default_title": "Click me!"
}
}
background.js which included a commented out attempt.
// On Extension Icon click, inject script
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file: "jquery-3.2.1.min.js"}, function () {
chrome.tabs.executeScript(tab.id, {file: "bootstrap.min.js"}, function() {
//chrome.tabs.insertCSS(tab.id, {file: "bootstrap.min.css", allFrames: "true"});
chrome.tabs.executeScript(tab.id, {file: "content_script.js"});
});
});
});
And my Content_Script file (reduced code not needed for question. Can post on request or on old posts of mine.)
// Handle page's frame (to allow DOM access)
var page = top.frames["TargetContent"].document;
**STUFF HAPPENS HERE.................**
function addPopover(profPage,profElement) {
// Retrieve & Format Professor Data
var name = profElement.textContent;
var quality = profPage.getElementsByClassName('grade')[0].textContent;
var difficulty = profPage.getElementsByClassName('grade')[2].textContent;
var ratings = profPage.getElementsByClassName('table-toggle rating-count active')[0].textContent;
ratings = ratings.trim();
// Concatenate into 1 string
var content = "Overall Quality: " + quality + "<br />" + "Difficulty: " + difficulty + "<br />" + ratings;
// Set attributes for popover
profElement.setAttribute("data-toggle","popover");
profElement.setAttribute("data-trigger","hover");
profElement.setAttribute("title",name);
profElement.setAttribute("data-content",content);
profElement.setAttribute("data-html",true);
$(profElement).popover();
}
Related
Running into a bit of an issue here after my extension has been published on the chrome store. The extension simply "busts" browser cache by appending a query param at the end of any url. It works fine if I upload the package directly to chrome locally for development but when the file is published on the chrome store (approved and all) it doesnt seem to work at all.
I am thinking that I might be missing some kind of permissions in the manifest but I am not certain.
The way that this is supposed to work is that you simply click on the extension icon and the background script fires off modifying the URL and reloading the page.
Thoughts would be much appreciated!
manifest.json
"manifest_version": 2,
"version": "1.0.1",
"name": "Cache Buster",
"description": "Allows a user to bust their cache without needing to type in the URL",
"permissions": [
"activeTab"
],
"browser_action": {
"default_icon": {
"16": "images/get_started16.png",
"32": "images/get_started32.png",
"48": "images/get_started48.png",
"128": "images/get_started128.png"
}
},
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
background script
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.query({active: true, lastFocusedWindow:true}, tabs => {
let url= tabs[0].url;
let busterDigits = [];
function findDigits() {
for (i =0; i < 4; i++) {
let n = Math.floor(Math.random() * 10);
busterDigits.push(n);
}
}
function checkParam() {
if ( url.includes("?") && !url.includes('beejBuster')) {
url = url + "&beejBuster=" + busterDigits.join("").toString();
} else if (url.includes("?") && url.includes('beejBuster')) {
url = url.split('beejBuster=')
url.pop()
url = url + 'beejBuster=' + busterDigits.join('').toString();
} else {
url = url + "?beejBuster=" + busterDigits.join("").toString();
}
}
findDigits();
checkParam();
console.log(url);
chrome.tabs.update({url: url})
})
});
});
Basically I am trying to create an Auto Visitor Extension for Chrome to open a website's URL after some specific time. When I open the popup everything works fine but when the popup is close nothing works. I am trying to find out a method to run that Auto Visitor Extension even when the popup is close I have read multiple questions regarding this phenomena on Stack Overflow but none of them clarifies what I am looking for.
Here is my manifest file:
manifest.json
{
"manifest_version": 2,
"name": "Auto Visitor",
"description": "This extension will visit multiple pages you saved in extension",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"permissions": [
"activeTab",
"storage",
"tabs",
"http://*/",
"https://*/"
]
}
The background file that i want to run even when popup is close :
background.js
// this will work only when you denie the background script in manifest
chrome.runtime.onInstalled.addListener(function(details) {
var initTime = 5;
chrome.storage.local.set({"avtime": initTime}, function() {});
});
reloadMainTab();
function reloadMainTab() {
chrome.storage.local.get('avurl', function (result) {
var urlsToLoad = result.avurl;
console.log(urlsToLoad);
if(urlsToLoad==undefined){
// do nothing
}else{
var urlsArr = urlsToLoad.split(",");
chrome.storage.local.get('avtime', function (result) {
var thisTime = result.avtime;
/*
setting it to -1 because it gets incremented by 1
when it goes into getSelected method
*/
var index=-1;
setInterval(function(){
if(index < urlsArr.length-1){
chrome.tabs.getSelected(function (tab) {
// console.log('index in get selected'+index)
chrome.tabs.update(tab.id,{url: urlsArr[index]});
});
index++;
}else{
index=-1;
}
}, thisTime+"000");
});
}
});
}
any help would be really appreciated
I'm tried to run script on ContextMenu Click event. I'm used example ContextMenu which have manifest:
{
"name": "Context Menus Sample (with Event Page)",
"description": "Shows some of the features of the Context Menus API using an event page",
"version": "0.7",
"permissions": ["contextMenus"],
"background": {
"persistent": false,
"scripts": ["sample.js"]
},
"manifest_version": 2
}
sample.js:
function onClickHandler(info, tab) {
chrome.tabs.executeScript(null,
{code:"document.body.style.backgroundColor='" + e.target.id + "'"});
};
chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
var contexts = ["page","selection","link","editable","image","video",
"audio"];
for (var i = 0; i < contexts.length; i++) {
var context = contexts[i];
var title = "Test '" + context + "' menu item";
var id = chrome.contextMenus.create({"title": title, "contexts":[context],
"id": "context" + context});
}
chrome.contextMenus.create({"title": "Oops", "id": "child1"}, function() {
if (chrome.extension.lastError) {
console.log("Got expected error: " + chrome.extension.lastError.message);
}
});
});
and i also change onclick handler to:
function onClickHandler(info, tab) {
chrome.tabs.executeScript(null, {file: "content.js"});
};
when content.js is:
document.body.innerHTML = document.body.innerHTML.replace(new RegExp("text", "gi"), "replaced");
but both of that doesn't working. How to solve it?
Because this question has hundreds of views so I will answer this my old question to help anyone who has the same problem. The answer is based on wOxxOm's comment. I just need to add activeTab permission to the manifest. So should be like this:
{
"name": "Context Menus Sample (with Event Page)",
"description": "Shows some of the features of the Context Menus API using an event page",
"version": "0.7",
"permissions": ["contextMenus","activeTab"],
"background": {
"persistent": false,
"scripts": ["sample.js"]
},
"manifest_version": 2
}
My script before doesn't work because I have code that needs to read/change current active tab content. activeTab permission gives an extension temporary access to the currently active tab when the user invokes the extension - for example by clicking its browser action.
I am writing my First Chrome Plugin and I just want to get some text present on the current webpage and show it as a alert when i click the Extension. Lets say I am using any any webpage on www.google.com after some Search query, Google shows something like "About 1,21,00,00,000 results (0.39 seconds) " . I want to show this Text as an alert when i execute my plugin. This is what i am doing.
here is the manifest.json that i am using
{
"manifest_version": 2,
"name": "Getting started example",
"description": "This extension shows a Google Image search result for the current page",
"version": "1.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["*://*.google.com/*"],
"js": ["content.js"]
}],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
]
}
Here is my popup.js
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("checkPage").addEventListener("click", handler);
});`
function handler() {
var a = document.getElementById("resultStats");
alert(a.innerText); // or alert(a.innerHTML);
}
Here is my content.js
// Listen for messages
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
// If the received message has the expected format...
if (msg.text === 'report_back') {
// Call the specified callback, passing
// the web-page's DOM content as argument
sendResponse(document.all[0].outerHTML);
}
});
Here is my background.js
var urlRegex = /^https?:\/\/(?:[^./?#]+\.)?google\.com/;
// A function to use as callback
function doStuffWithDom(domContent) {
console.log('I received the following DOM content:\n' + domContent);
}
// When the browser-action button is clicked...
chrome.browserAction.onClicked.addListener(function (tab) {
// ...check the URL of the active tab against our pattern and...
if (urlRegex.test(tab.url)) {
// ...if it matches, send a message specifying a callback too
chrome.tabs.sendMessage(tab.id, {text: 'report_back'}, doStuffWithDom);
}
});
1) run content scrip after document ready ** check "run_at"
"content_scripts": [{
"run_at": "document_idle",
"matches"["*://*.google.com/*"],
"js": ["content.js"]
}],
2) on click of extension make another js to run( popup js). The popup js has access to the ( open page document)
// A function to use as callback
function doStuffWithDom() {
//console.log('I received the following DOM content:\n' + domContent);
//get tabID when browser action clicked # tabId = tab.id
chrome.tabs.executeScript(tabId, {file: "js/popup.js"});
}
3) In popup JS simple you can set alert
var a = document.getElementById("resultStats");
alert(a.innerText); // or alert(a.innerHTML);
Just remove "default_popup" part in manifest.json, as you have listened to chrome.browserAction.onClicked event in background page. They can't live at the same time.
I made an Extension for Firefox that random check all radio buttons & checkboxes on a website. Now I will make it for Chrome.
JS (inject.js):
function randomFromTo(from, to){
return Math.floor(Math.random() * (to - from + 1) + from);
}
function autoFill () {
for (i = 0; i < document.forms.length ;i++) {
for (j = 0; j < document.forms[i].length ;j++) {
if (document.forms[i].elements[j].type == "radio") {
start = j;
lastName = document.forms[i].elements[j].name;
while (j < document.forms[i].length - 1 && lastName == document.forms[i].elements[j+1].name) {
j++;
}
rand = randomFromTo(start, j);
document.forms[i].elements[rand].checked = true;
}
if (document.forms[i].elements[j].type == "checkbox") {
start = j;
lastName = document.forms[i].elements[j].name;
while (j < document.forms[i].length - 1 && lastName == document.forms[i].elements[j+1].name) {
j++;
}
rand = randomFromTo(start, j);
document.forms[i].elements[rand].checked = true;
}
}
}
}
autoFill();
So I read a lot about inject.js and Content Scripts so I tried both. And made it like this.
{
"name": "Auto Check Radio \u0026 Checkbox",
"version": "0.0.1",
"manifest_version": 2,
"description": "",
"homepage_url": "",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_locale": "en",
"background": {
"page": "src/bg/background.html",
"persistent": true
},
"browser_action": {
"default_icon": "icons/icon16.png",
"default_title": "Autocheck",
"default_popup": "src/browser_action/browser_action.html"
},
"permissions": [
"tabs",
"notifications",
"http://*/",
"http://*/*",
"https://*/*"
],
"content_scripts": [{
"matches": ["https://*/*", "http://*/*"],
"js": ["src/inject/inject.js"],
"run_at": "document_end"
}],
"web_accessible_resources": ["src/inject/inject.js"],
"js": ["src/inject/inject.js"]
}
]
}
But I've got no idea how I can run the code. On Firefox it is much easier.
I don't need any background.html or browser_action.html
I only want to run the script - in the current tab - by clicking the icon.
Chould anyone give me a tip where i place my script?
Please read the Overview document first. Especially the Architecture part.
Any code that interacts with the page DOM must be in a Content Script. You've already put the code in src/inject.js.
Now, you don't need any UI to pop up when you click the button, so drop the "default_popup" item from the manifest and its HTML.
You also don't want your code to randomly execute when a tab loads. That's what "content_scripts" section in the manifest is about, so simply delete it.
Finally, you don't need a background HTML file. They have been replaced by autogenerated pages that are built from a list of scripts. So:
"background": {
"scripts": ["src/bg/background.js"]
},
"browser_action": {
"default_icon": "icons/icon16.png",
"default_title": "Autocheck"
},
Now, the only job of the background script is to register a handler for the button click. This is done through browserAction API:
// src/bg/background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file: "src/inject/inject.js"});
});
That's it, at this point it should work.
Now, to trim down the fat.
You don't need a persistent background page, since all it does is keeping simple event listeners that don't save any kind of state information. You can safely add "persistent": false to the manifest.
Your permissions are a massive overkill. There's a handy activeTab permission that gives you access to the current page if your code is invoked by, say, browser action button press.
In fact, that is the only permission your code needs. It will take care of executeScript call.
"permissions" : ["activeTab"],