My chrome extension which looks for a phone number on a webpage is not working. Essentially, i expect an icon to appear besides the number. It works on other websites, but not on say google.com search results page. E.g.: https://www.google.com/#q=macy's%20redmond Do you know why?
Here is my code.
reverphonescript.js:
var hostname = document.location.hostname;
if (hostname.indexOf('xp')== -1)
{
// Initiate recursion
wpReversePhoneLookup(document.body);
function wpReversePhoneLookup(elem) { // elem must be an element node
var nodes = elem.childNodes
, i = nodes.length
, regexp = /([\(]|)\d*([\+)]|)\d*[-\.\(\ ][0-9][0-9][0-9][-\s\.\)]*(([0-9][0-9][0-9][-\s\.][0-9][0-9][0-9][0-9])|([ ][1-9][0-9][0-9][0-9][0-9][0-9][0-9])|[1-9][0-9][0-9][0-9][0-9][0-9][0-9])]*/gi
, node, phoneNode, a, result;
while (node = nodes[--i]) {
if (node.nodeType === 1) {
// Skip anchor tags, nested anchors make no sense
//if (node.nodeName.toUpperCase() !== 'A')
wpReversePhoneLookup(node);
} else if (node.nodeType === 3) {
// Please note that the regexp has NO global flag,
// and that `node.textContent` shrinks when an address is found
while (result = regexp.exec(node.textContent)) {
//console.log(result);
node = node.splitText(result.index);
node = node.splitText(result[0].length);
phoneNode = node.previousSibling
//console.log(phoneNode)
var link = "https://pro.lookup.whitepages.com/phones?number=" + result[0];
var imgURL = chrome.extension.getURL("images/rsz_wp_16.png");
var img = new Image();
img.src = imgURL;
img.className = "wpChromeExtensionImg";
img.onclick = function() {
window.open( link ,"_blank" ,"width=1000, height=650");
};
document.getElementsByClassName("wpChromeExtensionImg").src = imgURL;
//Create link
wpLink = document.createElement('a');
wpLink.href = '#';
//Append phoneNode
wpLink.appendChild(img)
var refNode = phoneNode;
refNode.parentNode.insertBefore(wpLink, refNode.nextSibling);
}
}
}
}
}
And manifest.json:
{ // Required
"manifest_version": 2,
"name": "XP",
"version": "1.0",
"description": "XP Reverse Phone Lookup. ",
"icons": { "128": "images/rsz_xp_128.png"
},
"web_accessible_resources": [
"images/*.png",
"js/reversePhoneScript.js"
],
"browser_action": {
"default_icon": {
"19": "images/rsz_wp_19.png"
},
"default_title": "XP Reverse Phone Lookup"
},
"permissions": [
"tabs", "http://*/*", "https://*/*"
],
"content_scripts" : [
{
"matches" : ["http://*/*", "https://*/*"],
"js" : ["js/reversePhoneScript.js"],
"run_at" : "document_idle", //document_end
"all_frames" : false
}
]
}
Any help will be much appreciated.
Thanks,
Kushal.
use the chrome "inspect" tool to find your icon in the page. use the ctrl-f to find your icon in the page. https://developer.chrome.com/devtools/index
some css might be moving your icon to the far left of the screen, or much simply, no z-index tag is applied to your icon so it might be hiding behind something else. http://www.w3schools.com/CSSref/pr_pos_z-index.asp
Related
I´m writing a small program to autofill fields with a script.
It then submits the form.
However, once the form is submitted it reloads the page and the script runs again.
Hence, it is adding the user an infinite amount of times.
Ideally I want to add a user fill diferent information and add the next for up to 100 user.
I´m not sure how to stop this infinite loop, Im assuming the script also restarts when the page resets.
I
I tried placing a function that runs my script but since my script is run when the page loads, even though the function is in a for loop it runs non stop.
Its also hard to test since infinite loops are an issue you cant really get out of without it running to many times in first place.
My Manifest code is the following:
{
"name": "Begginer",
"version": "1.0",
"manifest_version": 2,
"description": "Fill",
// "permissions": [
// "activeTab",
// "*://*/*"
// ],
"content_scripts": [
{
"matches": ["website"],
"run_at": "document_end",
"js": ["Fill.js"]
}
],
"icons":
{
"16": "images/puppy16.png",
"48": "images/puppy48.png",
"128": "images/puppy128.png"
},
"browser_action":
{
"default_icon": "images/puppy128.png"
}
}
My JS:
// define your username and password
var Nam='Oi Macaco';
var Gen='M';
var Nbi='123';
var Ser='Servico';
var Dna='01-01-2000';
var Dab='01-01-2000';
var Cat='categorai';
var Dis='Lunda';
var Ema='email#domain.com';
var Npa='123';
var Una='OMacaco';
// Finds Each Field
var NameF = document.getElementById('nome_new');
var SexoF = document.getElementById('sexo_new');
var NbiF = document.getElementById('num_bi');
var SerF = document.getElementById('servico');
var DnfF = document.getElementById('data_nasc_func');
var DadF = document.getElementById('data_admissao');
var CatF = document.getElementById('categoria');
var DisF = document.getElementById('distrito');
var EmaF = document.getElementById('email_new');
var PasF = document.getElementById('password_new');
var UnaF = document.getElementById('unamesso_new');
// Fills the Fields
NameF.value = Nam;
SexoF.value = Gen;
NbiF.value = Nbi;
SerF.value = Ser;
DnfF.value = Dna;
DadF.value = Dab;
CatF.value = Cat;
DisF.value = Dis;
EmaF.value = Ema;
PasF.value = Npa;
UnaF.value = Una;
//Click Button
document.getElementById('Button1').click();
Everything is working, the problem is it runs an infinite number of times.
So I assume I can´t even add the Next User.
Everything is an assumption since its hard to test infinite loops, I wasnt really expecting it.
I think I should use chrome.browserAction.onClicked.addListener(function callback)
Then I should make a function that has a switch for every different user.
But that does not seem like the best way.
Help. Thx.
I solved it by inserting the following code:
Thanks to DanHarper,
Manifest
{
"name": "Inject",
"version": "0.0.1",
"manifest_version": 2,
"description": "Injecting stuff",
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"activeTab"
]
}
Inject.js
(function() {
// define your username and password
var Nam='Oi Macaco';
var Gen='M';
var Nbi='123';
var Ser='Servico';
var Dna='01-01-2000';
var Dab='01-01-2000';
var Cat='categorai';
var Dis='Lunda';
var Ema='email#somethin';
var Npa='123';
var Una='OMacaco';
// Finds Each Field
var NameF = document.getElementById('nome_new');
var SexoF = document.getElementById('sexo_new');
var NbiF = document.getElementById('num_bi');
var SerF = document.getElementById('servico');
var DnfF = document.getElementById('data_nasc_func');
var DadF = document.getElementById('data_admissao');
var CatF = document.getElementById('categoria');
var DisF = document.getElementById('distrito');
var EmaF = document.getElementById('email_new');
var PasF = document.getElementById('password_new');
var UnaF = document.getElementById('unamesso_new');
// Fills the Fields
NameF.value = Nam;
SexoF.value = Gen;
NbiF.value = Nbi;
SerF.value = Ser;
DnfF.value = Dna;
DadF.value = Dab;
CatF.value = Cat;
DisF.value = Dis;
EmaF.value = Ema;
PasF.value = Npa;
UnaF.value = Una;
//Click Button
document.getElementById('Button1').click();
alert('inserted self... giggity');
})();
Background code:
// listen for our browserAction to be clicked
chrome.browserAction.onClicked.addListener(function (tab) {
// for the current tab, inject the "inject.js" file & execute it
chrome.tabs.executeScript(tab.ib, {
file: 'inject.js'
});
});
EDIT #2
I've just tried selecting every div element on the website as each image is contained in a div. So, I used querySelectorAll followed with an if statement. The if statement checks the div and makes sure the image (class: FFVAD) is actually inside of the div before proceeding. But it's not working, it's now throwing a getElementsByClassName is not a function error.
My content script:
console.log('injected')
window.onload = function() {
var imagediv = document.querySelectorAll('div')
console.log('selected elements')
var i;
for (i = 0; i < imagediv.length; i++) {
imagediv[i].addEventListener('mouseover', function(el){
if (el.getElementsByClassName('FFVAD').length > 0) { //if the image with the class FFVAD is in the div
el.target.style.border = "7px solid red" //change the certain div's color
}
})
}
}
PREVIOUS QUESTION
I am developing a chrome extension which injects a javascript-written script into Instagram. I am trying to get the src of each image displayed on the users profile.
I have tried using document.querySelectorAll('img') to get every image element, but that isn't working. So, I took a peek in the developer console and noticed each image has a class called FFVAD. So, I used document.getElementsByClassName('FFVAD') (reference here). I also noticed each image has a div element as their parent. So, I tried doing this with my code:
My content script:
console.log('injected')
var image = document.getElementsByClassName('FFVAD') // instagram sets all
their images as the class FFVAD, as I looked in the inspect element window
console.log('selected elements')
while(image.length > 0){ //for every image
image[0].parentNode.addEventListener("mouseover", function (event) { //when the image's parent is hovered
event.style.border = "2px solid red";
});
image[0].parentNode.addEventListener("mouseout", function (event) { //when the image's parent isn't hovered
event.style.border = "none";
});
image[0].parentNode.addEventListener("click", function(event){ //when the image's parent is clicked
var child = event.childNodes; //get the image in the image's div
console.log(child[1].src) //log the src of the image
});
}
My exensions manifest:
{
"manifest_version": 2,
"name": "Testing",
"description": "Test extension",
"version": "0.0.1",
"author": "tester123",
"icons":{
"16": "icon.png",
"48": "icon2.png",
"128": "icon3.png"
},
"content_scripts": [{
"all_frames": false,
"js": ["imgselect.js"],
"matches": [ "https://*.instagram.com/*"],
"run_at": "document_end"
}],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs"
]
}
I used parentNode to get the parent of the image. I expect to see a red border around the image's div parent when it's hovered and seeing the src of the image in the console but I'm not seeing results. Any help will be appreciated, thank you!
This worked for me!
I looked deeper into the developer console and realized every image on Instagram is inside of multiple divs, so I put together this code that highlights the main div that contains the image, and it works perfectly!
console.log('injected')
function show(e) {
console.log("post found")
var img = this.getElementsByTagName('img')
for (i = 0; i <img.length; i++){
if (img[i].className == "FFVAD"){
console.log(img[i].src)
this.style.border = "5px solid red"
}
}
}
function hide(e){
var img = this.getElementsByTagName('img')
for (i = 0; i <img.length; i++){
if (img[i].className == "FFVAD"){
console.log(img[i].src)
this.style.border = "none"
}
}
}
setInterval(function(){
var imagediv = document.getElementsByClassName('KL4Bh')
var i;
for (i = 0; i < imagediv.length; i++) {
var parent = imagediv[i].parentNode
var secondparent = parent.parentNode
var thirdparent = secondparent.parentNode
var children = parent.children
if (children.length > 1){
children[1].remove()
thirdparent.addEventListener('mouseover', show)
thirdparent.addEventListener('mouseout', hide)
}
}
},1000)
I want to create a webExtension and I want to have icon in toolbar for this extension.
In my manifest.json file I put this code:
{
"manifest_version": 2,
"name": "test",
"version": "1.0",
"description": "test",
"icons": {
"48": "icons/icon48.png",
"96": "icons/icon96.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": [
"activeTab",
"contextMenus"
],
"browser_action": {
"default_icon": {
"19": "button/btn19.png",
"38": "button/btn38.png"
},
"default_title": "test"
}
}
When user click on this extension icon in toolbar, I want to get elements of current page and add < a > tag in document where I want. I put this java script code in background.js file. But these code doesn't execute.
How can I fix this?
background.js :
function change() {
var elems = document.body.getElementsByTagName("*");
var re = new RegExp(/abba\b/g);
for (var i = 0; i < elems.length; i++) {
var str = elems[i].innerHTML;
if (!str.match(/<[a-zA-Z0-9\s:./\"\'=\\;()-_]*>/) && re.test(str)) {
var aTag = document.createElement("a");
aTag.setAttribute('href', "test.php?t=" + str.match(/abba\b/)[0]);
aTag.setAttribute('target', "_blank");
aTag.innerHTML = " --**CHANGES**-- ";
elems[i].appendChild(aTag);
}
}
}
browser.browserAction.onClicked.addListener(change);
Background pages do not have access to the contents of the web page.
You need to use content scripts. Content scripts are injected into the page after page load on idle
Get more information from the documentation
to add a content script to your extension you can add this to manifest.json
"content_scripts": [{
"matches": ["*://*/*"],
"js": ["contentscript.js"]
}]
and then rename background.js to contentscript.js. This way the code is always executed on each page.
Or alternatively just create contentscript.js and move the contents change() function into it
contentscript.js:
var elems = document.body.getElementsByTagName("*");
var re = new RegExp(/abba\b/g);
for (var i = 0; i < elems.length; i++) {
var str = elems[i].innerHTML;
if (!str.match(/<[a-zA-Z0-9\s:./\"\'=\\;()-_]*>/) && re.test(str)) {
var aTag = document.createElement("a");
aTag.setAttribute('href', "test.php?t=" + str.match(/abba\b/)[0]);
aTag.setAttribute('target', "_blank");
aTag.innerHTML = " --**CHANGES**-- ";
elems[i].appendChild(aTag);
}
}
then background.js will call tabs.executeScript() when browser action clicked. This way it is only called when necessary
background.js:
browser.browserAction.onClicked.addListener(function(){
browser.tabs.executeScript({file: "/contentscript.js"})
});
I am working on an extension for Chrome. I wish to create hyperlinks 1) for every certain words (using RegExp), 2) automatically (before display), 3) in gMail message.
However, below codes doesn't work and gmail cannot load its message. Could you let me know why it happened and how I can fix it?
1.manifest.json
{
...
"content_scripts": [ {
"js": [ "content.js" ],
"matches": [ "<all_urls>" ],
"run_at": "document_start",
"all_frames": true
} ]
...
}
2.content.js
var doFilter = function(elem) {
//ID Moderators & URL parameters
var internalID = new RegExp(/[1-9]\d{7,8}/g);
var internalURL = 'https://mywebsite.com/go?customerId=';
//Create Hyperlinks for Internal ID
var internalMatch = elem.innerHTML.match(InternalID);
for (var i=0; i<internalMatch.length; i++) {
elem.innerHTML = elem.innerHTML.replace(internalMatch[i], '' + internalMatch[i] + '');
}
};
window.addEventListener("DOMContentLoaded", function() {
doFilter(document.body);
});
I'm trying to modify img src attribute by getting the url from different page. Thing is i need to find it by inspecting DOM as it's not static data; i will be looking via classes and IDs.
My knowledge of chrome extensions is very limited at the time. Basicly i just started.
Look at the "PSEUDO CODE" part of background.js
manifest.json
{
"manifest_version" : 2 ,
"name": "#####" ,
"version": "1.0" ,
"description": "#####" ,
"browser_action":
{
"name": "#####" ,
"icons": ["icon.png"] ,
"default_icon": "icon.png"
},
"content_scripts": [
{
"js": [ "jquery.min.js", "background.js" ] ,
"matches": [ "http://*.#####.com/encounters/promospp.phtml"] ,
"run_at": "document_end"
}]
}
background.js
var l = document.getElementsByTagName("div");
for (var i = 0; i < l.length; i++)
{
var obj = l[i].parentNode;
if (l[i].getAttribute("class") && l[i].getAttribute("class") == "user_contact")
{
var div = l[i];
var id = div.getAttribute("id").replace("u_", "0");
var profileUrl = "../" + id + "/";
var imgs = div.getElementsByClassName("userpic");
log("found img.userpic : " + imgs.length);
if (imgs && imgs.length > 0)
{
var img = imgs[0];
var alink = document.createElement('a');
img.parentNode.appendChild(alink);
alink.setAttribute("href", profileUrl);
alink.appendChild(img);
// PSEUDO CODE - the unknown
//
// download profileUrl page html
// search for given div element
// pull src attribute value from it
// apply it to img here
}
}
}
So in essence. How to download different page and work with it
Since you are including it already and tagged your question with it, I am going to answer with jQuery, I hope you don't mind. So first I rewrite what code you have in jQuery:
$('div.user_contact').each(function(){
var id = $(this)[0].id.replace('_u','0');
var profileUrl = "../" + id + "/";
var imgs = $(this).find('.userPic');
if(imgs.length > 0){
var alink = $(document.createElement('a'));
$(this).append(alink);
$(alink).attr('href',profileUrl);
$(alink).append(imgs[0]);
//Here is where you get the page and search for the div you want
$.get(profileUrl,function(data){
//Since I don't know the layout of what you are looking for
//I will just put in some placeholder
$(imgs).first().attr('src',$('img.youWant',data).first().attr('src'));
});
// Since $.get is asynchronous, doing it like this might cause problems
// if there is more than one div.user_contact.
// In the case where there are a low number of them and you are fine running
// blocking synchronous code, then you can do it with this instead:
// $.ajax(profileUrl,{async:false,success:function(data){
}
});
You'll also need to include permissions in your manifest for the site you are $.geting from. Something like this:
"permissions":["*://*.badoo.com/*"]
Using BeardFist solution + few fixes final code looks like this:
$('div.user_contact').each(function()
{
var id = $(this)[0].id.replace('u_','0');
log(id);
var profileUrl = "../" + id + "/";
log(profileUrl);
var imgs = $(this).find('.userpic');
if(imgs.length > 0)
{
var alink = $(document.createElement('a'));
$(imgs[0]).parent().append(alink);
$(alink).attr('href',profileUrl);
$(alink).append(imgs[0]);
$.get(profileUrl, function(data)
{
$(imgs[0]).attr('src',$('img.pf_phts_b_pht', data).attr('src'));
});
}
});
It works excelent. Entire html is inside data and it even stays loged and stuff :)