run window.open() in js performs different in chrome - google-chrome

We are developing a web application with javascript, we use chrome as our default browser for our users.
Now we met a problem when we use window.open in our application.
In our application, we need to open new page in a new browser tab, we used code : window.open('http://ourUrl.com', '_blank') in js code;
The action of the browser is different according to when this line of code is executed.
situation 1: user clicked a button, the click event will trigger our js function, in this function, execute this line of code directly, then the browser may open the page in a new browser tab. (this is what we want.)
situation 2: user clicked a button, in the handler of the button's click event, we firstly submit the data on page to our server via ajax, and in the callback function, we execute this line of code, it may pop an independent new window without tool bar instead of a browser tab.(this is not what we want).
I don't understand why the action of browser is different, anyone can help to explain?
Thanks.

As I explained on this question, in order for a URL to be opened in a new tab (not new window), the window.open function must be called within a scope of a user generated action callback (for example, within the scope of onClick)
In any other scenario, the URL will be opened in a new window.
To explain what you're experiencing:
Situation 1: window.open is invoked in a callback for a user generated action. That's why it's opened in a new tab.
Situation 2: In this situation, the window.open function is invoked in the scope of an ajax response callback, which is a different scope (outside the context of) the user generated action.
For the second scenario to open a new tab (instead of window) you need to call window.open synchronously, immediately after the user's click, and not as a callback of another action (ajax response).

Related

Check if a new if a new tab was opened with puppeteer

I am using Puppeteer to gather a list of companies that hire remotely. The page I am trying to collect the data from has a call to action that is not an <a href="" blank"_tab", but a <button></button>. The button doesn't have any data attribute either, that gives a hint as to what the URL of the page that gets opened in a new tab, when I click the button, is. I am now trying to find a way to catch the opening of the new tab, by clicking the said button, to then fetch the URL of the newly opened tab. Is this possible with puppeteer?
The solution is to extract all pages of the browser via the browser.pages() method call.
In your puppeteer project you always start by initialising the browser. The puppeteer virtual browser does contain the method pages(). Usage of pages().
What you have to do now: At first get the current url of the current page you are on. Then stream the result of the browser.pages() method. While streaming the array you can just get the index of your current tab. The tab you just opened using the button is the page with that index + 1 (the next element in the array)...
How to handle multiple tabs
Puppeteer Documentation about pages()

Changing chrome extension html using chrome storage event listener

With this code I want to create an event listener for whenever chrome storage updates.
I want 2 things to happen when the event listener is triggered:
The code will console log the updated values. This part works.
I want the HTML for the extension (the document that opens in the corner when you click the icon) to update and render the data value that is in chrome storage. This is that part I need help with.
chrome.storage.onChanged.addListener(function(changes, namespace) {
//part 1
console.log('New data type is %s. New value is %s',
changes['type'].newValue, changes['data'].newValue)
//part 2
document.getElementById('output').innerHTML =
changes['data'].newValue
});
I realize that calling "document" inside the function doesn't make sense, but I'm unsure how to move forward to get it to render in the extension's HTML.
I tried creating an event listener for when the context menu is accessed (users can update the chrome storage but clicking a button in the context menu) but I couldn't get it to work. Also the event should trigger when chrome storage is updated, not when the context menu is simply accessed.
Right now I get this error:
Error in event handler: TypeError: Cannot set property 'innerHTML' of null
(There is an element with id 'output', so that isn't the problem)
Thanks for your help!
The background script runs in a separate hidden background page. It's not related to the browserAction or pageAction popup page, it doesn't have any of the popup page elements, its DOM is empty except for the auto-generated script tags of the background scripts.
The popup is also a separate page and just like any normal page its environment/DOM exists only when the page is shown. You can't modify it when it's not shown. You can't show it from your code in general case either.
Solution 1
Put that onChanged listener in popup.js script that's loaded in your popup.html (declared as "browser_action": {"default_popup":"popup.html"} in your manifest.json) using the standard <script src="popup.js"></script> tag. It will update the popup page if it's shown, and to display the current values when the popup opens read them with chrome.storage.local.get or chrome.storage.sync.get depending on which storage you're using in your extension.
Solution 2
Use chrome.notifications API to show a small notification at the bottom of the screen, see also the official demo extensions.
Solution 3
Use chrome.browserAction.setBadgeText to display short text like a temperature right under the extension icon. Don't forget to declare at least "browser_action": {} in your manifest.json.

Chrome Extension -- Running executeScript in multiple new tabs at the same time

I'm building a Chrome Extension that has a popup.html with a search form. Like Travelocity or Kayak, the form includes checkboxes so the user can select which sites they want to query.
On submit, popup.js launches multiple new tabs based on the selected checkboxes. In the tabs.create() callback for each new tab I use executeScript to:
- (A) inject the user's query into the search form on each of the new pages, and
- (B) submit the search form on those pages.
My code is working when one checkbox is selected (i.e. new tab is launched), but when multiple new tabs are created simultaneously it appears that the executeScript isn't running consistently. Sometimes it works, and sometimes it doesn't.
This leads me to believe that there's some sort of issue with the timing of the script execution, but I'm not sure.
If you have any idea what's going on I'd love to hear your advice.
Also, I'd appreciate any resources on how to debug this sort of issue in the future.
Here's my code on github...
whole repo: https://github.com/rossmorey/SongSearch
manifest.json
popup.html
popup.js (most relevant file)
Many thanks!
Seems like when you open multiple tabs - your popup.html loses the focus and closes, so on tabs.create callbacks which injects your code will not be executed.
Try to create tabs with "active:false" option, like this:
chrome.tabs.create({url: stringToObj[org], active:false} ...
I think it would help you.
And also...
It's a bug in your SeSac inject-code: if no search type defined in popup window, block
input[value="undefined"]
will not be found, so "checked" property will be called on "undefined" and this will stop you inject script execution.

How to prevent reload of pages in Chrome Extension?

I have written a Chrome Extension to Clear TYPO3 CMS Caches right out of the browser's address bar.
Now I would like to add an optional feature, to clear the caches automatically on page refresh . That means, when the user presses F5, CTRL+R, clicks the reload icon in toolbar or clicks in context menu to "Reload", first my ajax script should be executed (to clear the CMS cache) and after it, the page may get reloaded.
Is there a possibility to do it with the Chrome API?
I tried first the window.onbeforeupdate event in content script - and this is triggered always when the page is reloading, but also if I close the window or switch to another website. And furthermore I can't tell the browser to wait for my ajax request here.
What works is to check in document.onkeydown event the keys 116 (F5) and 82 (R) with control key and use event.preventDefault(). But this will not cover the two other possible cases to refresh the cache.
Thanks!
I've found a solution. It does not really match my requirements, but it works (even better).
Chrome provides a webRequest API which allows you to modify or block all http requests.
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
if (!severalConditionsToCheckIfIWantToDoTheMagic) {
return;
}
$.ajax(url, {
async:false,
complete:function () {
return {redirectUrl:details.url};
}
});
},
{urls:["<all_urls>"]},
["blocking"]
);
In this example first I check if I want to do the ajax request. If yes, the next step is no do the ajax request. It is important, that the request is not asynchronous. On complete I return the original url of the request, which is basically just a reload.
The reason why it does not really match my requirements, is that it will be triggered always, on any request, not just on reload. That means in my conditions I have to check against:
Other websites
Other request types (loading css, js or images are also request), I just need the type 'main_frame'
Some variables belonging to my extension
Now, the script will be also triggered when I click on a link which is on the website - but for my case this is fine.

How to get the changed content in the page?

I wrote a user script for the latest Chrome browser. It seems the script can't get the changed content of the page after loaded (for example, after the page loaded, I clicked ¿sth? and an embedded window popped up).
Even if I used window.setTimeout(), I still can't the get updated content in the timer callback through document.getElementById(). I inspected the page and found that the popup element existed in the DOM.
Is this a limitation of user script? Or some other methods could be used to get the update in user script?
Update:
I tried DOMSubtreemodified event as suggested. But the behavior is still strange.
I added only one one line of JavaScript to the userscript for my.safaribooksonline.com,
document.addEventListener("DOMSubtreeModified", function () {
alert(eval('typeof OpenSignInPopup')); });
But the alert box shows "undefined" as the evaluate result of OpenSignInPopup. But I can run the alert statement in the script console in the same page at the same time, and shows the result as "function".
This function was not loaded when the user script is running at first. So how can I use it in the user script?
You need to provide details, like the relevant code snippet(s) and the pages targeted.
In general, you can fire off the DOMSubtreeModified event in chrome. That should get you access to the changed DOM.
Also, are you sure the new content is not in an iframe?
Update for new OP info:
But the alert box shows "undefined" as the evaluate result of OpenSignInPopup.
In Chrome, Greasemonkey code cannot interact with the page's JS functions like that. You'll need to inject your code into the page. See this SO answer for more information.