openerTabId in Chrome changed to undefined - google-chrome-extension

I'm writing a simple Chrome extension which tells the openerTabId of the active tab.
It works as excepted at first. But when I create a new tab and switch back to old tabs, all old tabs' openerTabId turns to undefined
Here's my code:
/////////////////////// popup.js ///////////////////////
'use strict';
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
for(var i=0; i < tabs.length; ++i) {
alert(tabs[i].id + ": opened from: " + tabs[i].openerTabId);
}
});
/////////////////////// popup.html ///////////////////////
<script src="popup.js"></script>
/////////////////////// manifest.json ///////////////////////
{
"name": "TabTest",
"version": "1.0",
"permissions": ["tabs"],
"browser_action": {
"default_popup": "popup.html"
},
"manifest_version": 2
}
Steps to reproduce:
open a tab, navigate to any website
click any link in the tab to open a child tab t1
click the browser action button to check the child tab's openerTabId id1
open a new blank tab
switch back to tab t1, click the browser action button to check the child tab's openerTabId id2
find that id1 != id2 && id2 is undefined
Any tips to the reason or any other reliable way to get a tab's parent?

Related

Performing browser action on two different pages

I have below files with me
manifest.json
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"name": "Test" ,
"browser_action": {
"icon":"icon.png"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icon.png"
},
"permissions":["https://myblog.com/*"] ,//Put All your URL here
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("https://myblog.com/page1.html")==0) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "page2.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
else if (tab.url.indexOf("https://myblog.com/page2.html")==0) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "page1.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
});
Page1.html
<html>
<head>
<title>Page1</title>
</head>
<body>
<input type='button' name='submit' id='myBtn' value='click here to move to next page' onclick="document.location.href='page2.html';" />
</body>
</html>
page2.html
<html>
<head>
<title>Page2</title>
</head>
<body>
<input type="text" name="textBox" id="myText" />
</body>
</html>
And to two JavaScript files page1.js and page2.
page1.js
var button=document.getElementById("myBtn");
button.click();
Page2.js
document.getElementById("myText").value="Text Box";
I have developed a Chrome extension. On first page when I click the Chrome extension icon the functionality is working good as per JavaScript file(page1.js) for https://myblog.com/page1 page.
And what I am doing on https://myblog.com/page1 page with the help of page1.js is to just click a button to move to second page that is https://myblog.com/page2. Now I want that page2.js should wrok on page https://myblog.com/page2 as scripted(page2.js) but its not working.
Script is working good when I click the extension icon on page1 and then again click the extension icon on page2.
But I want to extension icon should be clicked on page1 not repetitively.
Edited the Question
Added page1.html and page2.html
page1.js and page2.js
Is it possible to doing the same.
If yes where I am doing the mistake?
here's what you need to do.
Your code block chrome.browserAction.onClicked.addListener(function (tab) { makes the JS functions to execute only when you click the icon. That's why your Page 1 works whereas the Page 2 doesn't.
You want the page2.js to run as soon as the Page2.html is opened right? Hence change the coding of your Page2.html. Add the below code in the page2.html itself.
document.addEventListener("DOMContentLoaded", function(event) {
//Do work
});
What this will do is, as soon as the Page2.html is loaded, it will execute the Javascript. Eventhough it works in most of the browsers, but for IE 8 and below it won't.
If you need for IE 8 and below too, then try using the following code:
<script type="text/JavaScript">
function funtionToBeCalled(){
// code that will be exected after dom ready
}
window.onload=funtionToBeCalled;
</script>

Google Chrome: updating extension in "Developer mode" (locally) from userscript

I created an extension for Google Chrome which runs a small userscript for designated web-page and makes some requests via background.js to the chrome APIs (such chrome.tabs and others).
now, I'm testing it locally in "Developer mode" like this:
I edit my userscript.js and background.js;
then I go to chrome://extensions tab in Google Chrome and manually reload (CTR+R) my extension from local D:\my-extension folder.
finally, I switch to the tab with designated web-page and reload it to see the changes.
the problem is:
since I'm a beginner, a lot of changes have to be done to my userscript.js and background.js before my extension and userscript start working as expected.
so, this process involves a lot of monotonous switching between extensions and page tabs while testing.
the idea is:
it would be nice to add a button or a shortcut key on the page where the userscript is being tested and attach a sort of 'update_extension_and_reload_page' function to it in my userscript, so that evey time when I click this button it will call extension update from the local folder D:\my-extension then followed by page reload. (another alternative would be to assign such 'update_extension_and_reload_page' function to extension's browser_action icon.)
now, I'm just interested:
is there any sort of 'chrome.extesion.update' method, so that I could make a request to it from my userscript.js via background.js and call automatic reload of the extension (in "Developer mode") without need to go to the chrome://extensions tab.
The extension can reload itself, by calling chrome.runtime.reload(), so it's a matter of triggering the extension to do it.
The code below attaches the following functionality to the browser-action button:
Keeps track of the active tab.
Reloads the extension.
Reloads the active tab.
manifest.json
...
"browser_action": {
"default_title": "Reload"
// "default_icon": {
// "19": "img/icon19.png",
// "38": "img/icon38.png"
// },
},
...
background.js
chrome.browserAction.onClicked.addListener(function (tab) {
localStorage.tabToReload = tab.id;
chrome.runtime.reload();
});
function reloadTab() {
var tabID = localStorage.tabToReload;
if (tabID) {
chrome.tabs.reload(parseInt(tabID));
delete(localStorage.tabToReload);
}
}
reloadTab();
...
See, also, this answer on how to automate the re-loading process.
is this what you are looking for?
https://chrome.google.com/webstore/detail/extensions-reloader/fimgfedafeadlieiabdeeaodndnlbhid
Credit goes go
How do I auto-reload a Chrome extension I'm developing?
slightly modified the ExpertSystem's code above to call reload of extension followed by reload of tab where the content script (userscript.js) is being performed, all triggered by #reload-btn button (in case the browser_action icon is occupied with popup.html).
manifest.json
...
"background":{ "scripts": ["background.js"]},
"content_scripts" : [{
"matches" : ["https://stackoverflow.com/*"],
"css": ["userscript.css"],
"js": ["jquery-latest.min.js", "userscript.js"],
"run_at":"document_end"
}],
"web_accessible_resources": ["jquery-latest.min.map"],
"permissions": ["tabs"],
"browser_action": {
"default_icon": "icon19.png",
"default_title": "My Extension Title",
"default_popup": "popup.html"
}
...
userscript.css
...
#reload-btn { position: fixed; top: 0; right: 0; } /* or any other position on the page */
...
userscript.js
...
$("body").prepend("<button id='reload-btn'>reload extension + page reload</button>"); // some shortcut key can be additionally assigned to this button
$("#reload-btn").on("click", function() {
chrome.runtime.sendMessage("please, reload me");
});
...
background.js
...
chrome.runtime.onMessage.addListener(
function(message, sender) {
if (message == "please, reload me"){
localStorage.tabToReload = sender.tab.id;
chrome.runtime.reload();
}
});
function reloadTab() {
var tabID = localStorage.tabToReload;
if (tabID) {
chrome.tabs.reload(parseInt(tabID));
delete(localStorage.tabToReload);
}
}
reloadTab();
...

Executing Chrome extension onclick instead of page load

I created a Chrome extension that works as expected except that it only executes when I load a page that matches the conditions in the manifest. I have tried for hours to make it execute by clicking on the extension icon to no avail.
The closest I have been able to what I want is that I have been able to make the extension icon click to run the code, but then it does not run it on the loaded page. It runs it on the extension's space instead of the page DOM.
In the current state my code only runs when a page in the specified domain opens. I want to run it only when it matches that rule, but only when I click the extension icon.
Here is my code:
manifest.json
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_icon": "mkto_icon.png",
"name": "Click to get URL"
},
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["http://mydomain.com/*"]
}]
}
contentscript.js
if (document.getElementsByName("returnURL")){
alert("\nThe Response URL on this form is:\n\n" + document.getElementsByName("returnURL")[0].value);
}
As i see you want to run code when
User has clicked on Browser Action ICON and
URL pattern is a match
If so, you have use
Background pages in conjunction with Tabs API.
Demonstration
This is a sample demonstration of your use case and you can put all your code and assign permissions for all match URL(s).
manifest.json
Registered Background Page, Browser Action and Permissions for Target Pages.
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"name": "Click to get URL"
},
"background":{
"scripts":["background.js"]
},
"permissions":["https://www.google.co.in/*"] //Put All your URL here
}
background.js
Put all Your Target Matching URL in a series of if conditions here
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("https://www.google.co.in/") != -1) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "contentscript.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
});
contentscript.js
alert("Code Executed ... ");
Output
When you browse to https://www.google.co.in/ and after click of browser action you see Alert in the page.
References
Tabs API
Background Pages
use browserAction API ,see here
the onClick events may help you. also see these exsamples from google :

Timer for chrome extension [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Chrome extension delay condition
Im very beginner at extensions and by collecting codes from here and there I created a simple one which collects the tab's url (works for specific website) and using ajax Im sending it to my server in order to store it in my database.
What Im trying to do is to add a timer so the browser button will be disabled (or do nothing) if the previous click occured in less than 5 seconds.
Below is the structure of the extension:
Manifest:
{
"name": "The name",
"icons": { "16": "Big.png",
"48": "Big.png",
"128": "Big.png" },
"version": "1.0",
"manifest_version": 2,
"description": "and the description",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "<all_urls>"]
}
popup.js:
chrome.tabs.getSelected(null,function(tab) {
var Mp=tab.url
if(Mp=='http://www.examplesite.com')
{
var xhr=new XMLHttpRequest();
var Params;
xhr.open("POST", "http://myserver.com/post_from_extension.asp", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
Params='Url=' + tab.url;
xhr.onreadystatechange=function()
{
if(xhr.readyState==4)
{
message.innerHTML=xhr.responseText;
}
}
xhr.send(Params);
}
else
{
message.innerHTML='<span style="font-family: Segoe UI, Tahoma;color: #f00">This is not a valid url</span>';
}
});
popup.html
<!DOCTYPE html>
<html style=''>
<head>
<script src='popup.js'></script>
</head>
<body style="width:400px;">
<div id='message'><span style="font-family: Segoe UI, Tahoma;color: #00f">Sending request</span></div>
</body>
</html>
As a side question, is there any other method to post the url in my database, if not with Ajax?
Thank you for reading me.
I think you should add a background page (script) to your extension - this is a kind of application state. Add this in the manifest:
"background": {
"scripts": ["background.js"]
},
Then in the page you can define an array storing last times when browser action was performed for each tab.
var timers = [];
You can update this array's elements from your popup.js, something like that (in getSelected callback):
chrome.extension.getBackgroundPage().timers[tabId] = new Date();
chrome.browserAction.disable(tabId);
chrome.browserAction.setIcon({path: "icon-disabled.png", tabId: tabId});
Note how you can disable browser action and change its appearence to a disable/grayed one.
When a period passed since the registered time exceeds 5 seconds you should re-enable the button from the background page.
var currentTime = new Date();
if(currentTime - chrome.extension.getBackgroundPage().timers[tabId] > 5000)
{
chrome.browserAction.enable(tabId);
chrome.browserAction.setIcon({path: "icon-enabled.png", tabId: tabId});
}
You can execute this code from setInterval callback and within a cycle through all elements in the timers array.

Chrome Page Action click not working

this is my manifest.json file
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"background_page": "background.html",
"page_action":
{
"default_icon": "icon.png"
},
"permissions" : [
"tabs"
]
}
This is the background.html
<html>
<head>
<script>
// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
// If the letter 'page' is found in the tab's URL...
if (tab.url.indexOf('google') > -1) {
// ... show the page action.
chrome.pageAction.show(tabId);
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
chrome.pageAction.onClicked.addListener(function(tab)
{
tab.url = 'www.bing.com';
console.log('I am clicked');
}
);
</script>
</head>
</html>
when i click on the page action icon , i want to redirect the page to Bing.com, but this click event is not working for me.
Thanks
If you want to redirect a tab you need to use:
chrome.tabs.update(tab.id, {url: "http://www.bing.com"});
You also need to check for status of the page as checkForValidUrl will be executed twice for every page:
function checkForValidUrl(tabId, changeInfo, tab) {
if(changeInfo.status === "loading") {
//...
}
});
Have u tried using javascripts window.location function instead? e.g:
window.location="http://www.bing.com";
If that doesn't work then it's probably a problem with your event listener I would have thought.

Resources