How to trigger click on a button - google-chrome-extension

I've this page. I need to trigger a click on the BUY NOW button on this page using AngularJS.
I've tried these ways to click on this "BUY NOW" in content script(myscript.js) but does not work:
angular.element($('ul form button:contains("BUY NOW")').get(0)).triggerHandler('click');
$('ul form button:contains("BUY NOW")').get(0).click();
$('ul form button:contains("BUY NOW")').get(0).dispatchEvent(new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
}));
The manifest.json looks like this:
"content_scripts": [
{
"run_at": "document_end",
"all_frames": false,
"matches": ["*://www.flipkart.com/*"],
"css": [ "jqueryui/jquery-ui.css", "js/slidenavi/sidenavi-right.css","main.css", "js/bootstrap-switch-master/dist/css/bootstrap3/bootstrap-switch.min.css"],
"js": ["jquery-2.1.4.min.js", "jqueryui/jquery-ui.min.js","js/angular.min.js", "js/jquery.cookie.js", "jqueryui/jquery-ui.min.js","js/slidenavi/SideNavi.js", "client_server_common.js", "user-selections.js",
"jquery.countdown.min.js", "js/bootstrap-switch-master/dist/js/bootstrap-switch.min.js", "js/cryptojs/rollups/md5.js", "common.js",
"myscript.js"
]
}
],
What is the way to make it work?

Try with this code; it simulates a mouse left click on the element by a quick succession of mousedown, mouseup and click events fired in the center of the button:
var simulateMouseEvent = function(element, eventName, coordX, coordY) {
element.dispatchEvent(new MouseEvent(eventName, {
view: window,
bubbles: true,
cancelable: true,
clientX: coordX,
clientY: coordY,
button: 0
}));
};
var theButton = document.querySelector('ul form button');
var box = theButton.getBoundingClientRect(),
coordX = box.left + (box.right - box.left) / 2,
coordY = box.top + (box.bottom - box.top) / 2;
simulateMouseEvent (theButton, "mousedown", coordX, coordY);
simulateMouseEvent (theButton, "mouseup", coordX, coordY);
simulateMouseEvent (theButton, "click", coordX, coordY);

What about Vanilla JS, noone prohibited?
Such as "onlick/click"?
function ae(a,b,c) {
if (a.addEventListener)
a.addEventListener (b,c,false);
else if (a.attachEvent)
a.attachEvent ('on'+b,c);
}
function re(a,b,c) {
if (a.removeEventListener)
a.removeEventListener (b,c,false);
if (a.detachEvent)
a.detachEvent ('on'+b,c);
}

Related

How to block a tab from opening a page on webNavigation.onBeforeNavigate event?

As a learning exercise I'm attempting to build an example Chrome extension that ensures sites on a 'greylist' are always opened in an incognito window.
Here's how far I have got - using the webNavigation.onBeforeNavigate event fired when a grey listed page is about to be navigated to I open a new tab in an incognito window, but now need to prevent the original tab from opening the page.
manifest.js:
"permissions": [
"webNavigation",
"tabs"
],
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
background.js:
chrome.webNavigation.onBeforeNavigate.addListener(function(details) {
chrome.tabs.get(details.tabId, function(tab) {
if(!tab.incognito) {
// Open the page in an incognito window
chrome.windows.create({ url: details.url, incognito: true});
// TODO stop non-incognito tab opening page!
}
});
}, {
url: [
{ hostEquals: 'badsite.com' }
],
});
To stop the navigation use window.stop() by injecting a content script in the tab:
chrome.tabs.executeScript(details.tabId, {code: 'window.stop()'});
Add a permission in manifest.json, otherwise you'll see an error in the background page console:
"permissions": [
"webNavigation",
"tabs",
"<all_urls>"
],
Partial answer arrived at from wOxxOm's input and further experiments and reading - to at least document what I found out.
manifest.js:
"permissions": [
"webNavigation",
"tabs",
"<all_urls>" // Note: Permission
],
...
background.js:
// Note: onCommitted
chrome.webNavigation.onCommitted.addListener(function(details) {
chrome.tabs.get(details.tabId, function(tab) {
if(!tab.incognito) {
// Stop non-incognito tab opening page
// Note runAt: "document_start"
chrome.tabs.executeScript(details.tabId, { runAt: "document_start", code: 'window.stop(); '})
// Open the page in an incognito window
chrome.windows.create({ url: details.url, incognito: true});
}
});
}, {
url: [
{ hostEquals: 'badsite.com' }
],
});
Listening for chrome.webNavigation.onCommitted events instead of onBeforeNavigate allows the script injected by chrome.tabs.executeScript to run when a grey listed page is navigated to from a new tab and a url is pasted into the omni box.
This prevents the grey listed page from being displayed, but the page is at least partially loaded. A history entry is not created but cookies or local storage items are created, so it does not meet the ultimate need of my original question.
two ways:
base on #wOxxOm
chrome.webNavigation.onBeforeNavigate.addListener((details) => {
chrome.tabs.executeScript(tabid,{code: 'window.stop()'});
});
not refresh
window.history.pushState(“object or string”, “Title”, “/new-url”);

Why does chrome.tabs.create create 2 tabs?

When the chrome.tabs.create function is triggered by a message received, it creates 2 tabs. In the following demo code, 1 cat tab is created, and 2 dog tabs are created.
Is this by design or is it a bug? If it is a known bug, can you provide the bug id so I can track its progress? How can I avoid 2 duplicate tabs being created?
The debug console contains the following output, so in fact the duplicate tab is also getting the content script injected even though only one call to secondaryTabCreationCallback_ is printed in the debug output!!!!
Creating secondary tab
Created secondary tab: 11968
Kill request from tab: 11966
Kill request from tab: 11968
background.js
var handler = {
url1_: 'https://www.google.com/?gws_rd=ssl#q=cat',
url2_: 'https://www.google.com/?gws_rd=ssl#q=dog',
windowId_: chrome.windows.WINDOW_ID_CURRENT,
createPrimaryTab: function() {
chrome.tabs.create(
{'url': handler.url1_, 'active': false, 'windowId': handler.windowId_},
handler.primaryTabCreationCallback_);
},
primaryTabCreationCallback_: function(tab) {
chrome.tabs.executeScript(tab.id, {file: "content_script.js"});
},
createSecondaryTab_: function() {
console.log("Creating secondary tab");
chrome.tabs.create(
{'url': handler.url2_, 'active': false, 'windowId': handler.windowId_},
handler.secondaryTabCreationCallback_);
},
secondaryTabCreationCallback_: function(tab) {
console.log("Created secondary tab: " + tab.id);
chrome.tabs.executeScript(tab.id, {file: "content_script2.js"});
},
};
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
switch (message.type) {
case "CREATE_TAB":
handler.createSecondaryTab_();
break;
case "KILL_ME":
console.log("Kill request from tab: " + sender.tab.id);
// chrome.tabs.remove(sender.tab.id);
break;
default:
alert("Not Reached");
break;
}
});
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('background.html')});
});
window.onload = function() {
document.getElementById("start_button").onclick = handler.createPrimaryTab;
}
content_script.js
chrome.runtime.sendMessage({type: "CREATE_TAB"});
content_script2.js
chrome.runtime.sendMessage({type: "KILL_ME"});
background.html
<!doctype html>
<html>
<head>
<script src="background.js"></script>
</head>
<body>
<div>
<input type="button" id="start_button" value="Start">
</div>
</body>
</html>
manifest.json
{
"manifest_version": 2,
"name": "Tab Bug",
"description": "Demonstrates bug in chrome.tabs.create.",
"version": "1.0",
"permissions": [
"activeTab",
"nativeMessaging",
"tabs",
"https://www.google.com/"
],
"icons": { "128": "icon128.png" },
"browser_action": {
"default_icon": "icon19.png"
},
"background": {
"page": "background.html"
}
}
The issue is that there are 2 "background" pages running.
The official background page specified in the manifest file.
The tab created by chrome.tabs.create({'url':
chrome.extension.getURL('background.html')}).
This means there are 2 message listeners, which is why 2 tabs are opening.
The console messages from the official manifest.json background can be found by looking at extension on the chrome extensions page and click on the "Inspect views: background.html". Which shows:
Creating secondary tab
Created secondary tab: 11966
Kill request from tab: 11966
Kill request from tab: 11968
To work around this issue. The manifest.json background file can point to a script "starter.js" instead of an html page, which simply has the following javascript:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('background.html')});
});
My background.js is very simple.
chrome.browserAction.onClicked.addListener(() => {
chrome.tabs.create({
url: chrome.runtime.getURL('popup.html'),
})
})
manifest.json
"background": {
"persistent": false,
"scripts": [
"background.js"
]
},
Tried to disable/enable the extension (so that chrome destroys all the background pages from this extension) but it still opens duplicate tabs!!
So the problem might be there is someone that included the background.js. And guess what! It's popup.html.
The root cause is HtmlWebpackPlugin from webpack.config.js. It defaults to include all chunks (including background).
So we just exclude the background chunk from popup.html config then it should work as expected.
new HtmlWebpackPlugin({
template: 'public/popup.html',
filename: 'popup.html',
excludeChunks: ['background'],
}),

Sencha Architect View Disappearing after first setActiveItem

Here is the problem. I have a view
Ext.define('Journal.view.CreateGoal', {
extend: 'Ext.form.Panel',
It is part of main
Ext.define('Journal.view.Main', {
extend: 'Ext.Container',
requires: [
'Journal.view.GoalList',
'Journal.view.CreateToDo',
'Journal.view.Choice',
'Journal.view.CreateGoal'
],
config: {
layout: {
type: 'card'
},
items: [
{
xtype: 'GoalList'
},
{
xtype: 'createtodo'
},
{
xtype: 'choice'
},
{
xtype: 'creategoal'
}
]
}
});
I have a button in GoalList that fires
var createGoalForm= Ext.create('Journal.view.CreateGoal');
console.log('create goal view');
Ext.Viewport.setActiveItem(createGoalForm);
The first time I press that button, everything is fine.
If I have used a back button that triggers either of these
Ext.Viewport.setActiveItem(0);
or
Ext.Viewport.setActiveItem(Journal.view.GoalList);
The next time I press the button I do not see the contents of createGoalForm
The console.log still fires, so it's getting into the function.
I tried several methods such as
Ext.Viewport.setActiveItem(Journal.view.CreateGoal);
and a few others. Each version I have tried, the first time I go to the view its fine, every other time its blank.
I have changed the autoDestroy setting to no avail.
So what am I doing wrong?
Thanks

Why does "waiting" or "waitFor" dissapear in my code?

OK Ive updated the code to be as small as possible and still get the error...although now the question isnt quite right...it should now be "Why does waitFor jump out of the sandbox?" (but Ive been told not to change questions for a post, sorry if this is bad form). If you install this extension and follow the below instructions youll see waitFor get transferred to out side the content scripts sandbox.
To see this error.....
Go to....
https://www.facebook.com/groups/382415791793391/
..wait for the page to fully load.
Then click on the tab "Testy Testy" to cause the page to refresh.
Have a look in the console and youll see "You shouldnt be able to see this".
The console output for me looks like this....
chekcpage
waitFor
(19)waitFor
pop
attach contentNodeRemoved
chekcpage
waitFor
removing
added
attach contentNodeRemoved
chekcpage
waitFor
(156+)You shouldnt be able to see this
myscript.js
script = function(old) {
window.variableInUnsafeWindow = "You shouldnt be able to see this";
}
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.documentElement.appendChild(script); // run the script
document.documentElement.removeChild(script); // clean up
}
exec(script);
window.onpopstate = function(event) {
console.debug('pop');
checkPage();
};
function waitFor(query, delay) {
if (typeof(variableInUnsafeWindow) == "undefined") {
console.debug('waitFor');
found = document.documentElement.querySelector(query);
if (!found) {
window.setTimeout("(" + waitFor + ")('" + query + "'," + delay + ");", delay);
}
} else {
console.debug(variableInUnsafeWindow);
window.setTimeout("(" + waitFor + ")('" + query + "'," + delay + ");", delay);
}
}
function contentNodeRemoved() {
console.debug('removing');
document.querySelector('div#contentCol').removeEventListener('DOMNodeRemoved', contentNodeRemoved, false);
document.querySelector('div#contentCol').addEventListener('DOMNodeInserted', contentNodeAdded, false);
}
function contentNodeAdded() {
console.debug('added');
document.querySelector('div#contentCol').removeEventListener('DOMNodeInserted', contentNodeAdded, false);
checkPage();
}
function checkPage() {
if (document.querySelector('div#contentCol')) {
console.debug('attach contentNodeRemoved');
var node = document.querySelector('div#contentCol');
node.addEventListener('DOMNodeRemoved', contentNodeRemoved, false);
}
console.debug('chekcpage');
waitFor('ul#group_mall_382415791793391', 300);
}
checkPage();
manifest.json
{
"name": "Facebook - Group member ban icon",
"description": "Puts an X after a users name on the groups page for banning. Unfortunately the X show on groups your not an Admin of still.",
"content_scripts": [{
"matches": ["*://*.facebook.com/*"],
"js": ["myscript.js"],
"run_at": "document_start"
}],
"permissions": ["tabs"],
"icons": {
"16": "icon.png",
"48": "icon48.png",
"128": "icon128.png"
},
"version": "1.0"
}

Render context menu depending on selection

I want to display a different menu option depending on whether a number or text is selected.
I've tried playing with content scripts but I can't get them to work in gmail which is where I need it to work. Here is what I have, it works on sites other than gmail (is it a https thing?)
Background.html
<script src="driver.js"></script>
content_script.js
document.addEventListener("mousedown", function(event){
if(event.button == 2) {
var selection = window.getSelection().toString();
chrome.extension.sendRequest({cmd: selection});
}
}, true);
driver.js
chrome.extension.onRequest.addListener(function(request) {
alert(request.cmd);
});
manifest.json
{
"name": "Context Menu Search",
"description": "Opens the selected text as keyword in a new window",
"version": "0.1",
"permissions": ["contextMenus"],
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js": ["content_script.js"]
}
],
"background_page": "background.html"
}
Selection type changes context menu using chrome extension
You will have to set a listener for mouse down. There is no other way to get the selected text before the menu is created.
See this SO question:
chrome extension context menus, how to display a menu item only when there is no selection?
Here is part of the code the rest is at the link.
document.addEventListener("mousedown", function(event){
//right click
if(event.button == 2) {
if(window.getSelection().toString()) {
chrome.extension.sendRequest({cmd: "createSelectionMenu"});
} else {
chrome.extension.sendRequest({cmd: "createRegularMenu"});
}
}
}, true);

Resources