I'm creating a Safari Extension. At one point, I want to open a new tab/window and enter text on some text fields in that new tab.
This is what I tried.
var newWindow = window.open('http://openradar.appspot.com/myradars/add', "new tab");
var fillContent = function () {
//Fill some content
//This never get called
};
newWindow.onload = fillContent;
The problem is that the function never get called.
During debugging, I saw that newWindow is valid but that newWindow.onload is always undefined, before and after newWindow.onload = fillContent;
Is it possible to do what I'm trying to do? Is there a better way?
If the page you are trying to open is in another domain, it's impossible, because you were violating javascript's same origin policy (which states that you can only 'control' pages that are on the same domain where the script is running).
Related
I have a button in my homepage that opens to a new window FindAPark.html. I'm trying to pass a variable to that HTML page without GET.
I've tried this in my Homepage.js:
function buttonClick() {
var newWindow = window.open('FindAPark.html');
newWindow.my_special_setting = "Hello World";
}
And then in my FindAPark.js:
window.my_special_setting;
console.log(window.my_special_setting);
The console says it's "undefined" instead of showing "Hello World". What might be the problem, and what might fix it?
EDIT: Now it's telling me "Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame." I haven't hosted these on a domain yet, but I own both HTML files. What do I do?
Use window.postmessage
In the opened window
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
console.log(event)
// ...
}
Now dispatch the event from the parent window
newwindow.postMessage("The user is 'bob' and the password is 'secret'",
"https://secure.example.net");
Use localStorage like this:
function buttonClick() {
localStorage.setItem("mySepcialSetting", "Hello World");
window.location.href = "FindApark.html";
}
Then you can access it as follows:
var mySpecialSetting = localStorage.getItem("mySepcialSetting");
console.log(mySpcialSetting);
Provided your opened window is from the same security domain, you can pass the variable like you did in your question, but you should wait for the new window to completely load.
let newWindow = window.open('FindAPark.html');
newWindow.addEventListener('load', function(){
newWindow.my_special_setting = "Hello World";
}, false);
Another option is to read a variable from the window that opens the new window... same security policies apply as above.
let my_special_setting = window.opener.my_special_setting;
Below is my code.
It is resulting in unexpected behaviour.
It navigates to bing.com but it does not fill in the text field. Also, I have noticed that the console get cleared after navigating to a new webpage.
window.location = "https://www.bing.com";
window.onload = function(){
var editSearch = document.getElementById("sb_form_q");
editSearch.value = "Quux";
}
You are binding the onload function to the existing window object.
When the browser loads the new page, it will make a new window object which won't have your property set on it.
JavaScript run in one page (even when you are running it through developer tools) can't persist variables onto a different page.
(Storage mechanisms like localStorage and cookies are available, but you would need code in the subsequent page to look for them).
JavaScript is only valid for the current page you are on. When you are executing code from DevTools console, you are executing code on that page itself. So, when you navigate to another page using window.location you loose the onload handler you have defined.
To add handlers to a different page, it must be connected to your page (the parent) in some way, like an iframe or a popup.
ifrm = document.getElementById('frame');
ifrm.src = 'http://example.com';
ifrm.contentWindow.onload = function () {
// do something here with
// ifrm.contentWindow.document.getElementById('form')
}
As #Quentin said.
But you can do another way like ..
var keyword = "Quux";
window.location = "https://www.bing.com/search?q="+keyword;
I am working on a web based application, in which I have to open popup window. I am using window.open() method to open the popup, like this:
window.open(url, "popupWin");
where url contains the URL I would like my popup window to navigate to. Now, the problem is, if I execute window.open() from multiple tabs (with same or different URLs), at least on Chrome, it might / might not give you the same window which was opened earlier. This behaviour is inconsistent, I mean, either it should get me fresh window every time, or it should get me previously opened window every time.
I need to persist the same popup window for entire domain. How can I do that?
Well looks like there is a direction to go or at least to give it a try.
It fully remains on localStorage which gives you ability to share the knowledge across your tabs within a single domain.
The code I give below does not work yet (it is only a direction), so don't expect too much from running it as it is.
What it does: it saves the popups by the url in a localStorage and when you try to open a new one with the same url it won't do that. If you don't want to distinguish them by URL it is even simpler: store boolean in a localStorage instead of an object.
What it does not do but should:
it should listen to the popup onunload (close) event and reset the localStorage information accordingly. Best for you here is just to set your localStorage boolean value to false
it should listen to the current tab onunload (reload, close) event and also reset something according to Your logic. As I understand the best for you would be just check whether this tab is the last one from your domain (you can also do this using localStorage, e.g. on every new tab adding its identifier, e.g. creation timestamp and destroying it on tab close) and if it is set your localStorage boolean value to false.
This, I think, would be enough to solve the problem. And finally a small piece of code:
// get the localstorage url map
function getOpenPopups() {
var obj = localStorage.getItem('mypopups');
return obj ? JSON.parse(obj) : {};
}
// set the localstorage url map
function setOpenPopups(object) {
localStorage.setItem('mypopups', JSON.stringify(object))
}
// open the popup
function popup(url, title) {
var popups = getOpenPopups();
// check whether popup with this url is already open
// if not then set it and open the popup
if (!popups[url]) {
popups[url] = true;
setOpenPopups(popups);
return window.open('abc', 'cde');
}
else {
return false;
}
}
jsFiddle
From w3c documentation we can see that window.open() returns a reference to the newly created window, or null if the call failed. That means we can keep it in memory and check for closed flag of that window.
var newWindow = window.open('/some/path', 'TestWindow');
// ...
if (!newWindow.closed) {
}
Keep in mind that if window with following name exists, page will be loaded in the same window without opening new one.
Other variants of name parameter like _blank, _self, _top, _parent you can find in official docs too.
My script opens a new window and then writes its content. The destination window displays "Hello World" as expected, but the URL is the same as the window that the script ran in and I don't understand why.
Is there a way to build a new window without picking up the old URL?
function doTest() {
var impl = document.implementation;
var tempDoc = impl.createHTMLDocument("Hello");
var tempBody = tempDoc.getElementsByTagName("body")[0];
var tempDiv = tempDoc.createElement('div');
var tempMsg = tempDoc.createTextNode('Hello World.');
tempDiv.appendChild(tempMsg);
tempBody.appendChild(tempDiv);
var destWindow=window.open("about:blank", "title", null, false);
var destDoc=destWindow.document;
destDoc.open();
destDoc.write("<html>"+tempDoc.documentElement.innerHTML+"</html>");
destDoc.close();
}
var btnTest = document.createElement( 'input' );
btnTest.setAttribute( 'value', 'Test' );
btnTest.setAttribute( 'type', 'button' );
btnTest.addEventListener('click',doTest,true);
document.body.appendChild( btnTest );
I'm using Firefox 20 and Greasemonkey 1.8.
I don't think you can do this. This is probably a security feature; see BugĀ 337344, "Disable location bar hiding by default, to make chrome spoofing harder" and related bugs.
I think that as soon as parent-window javascript tries to alter the content, then the anti-spoofing protection forces the location to the opener's URL. This is true even if you open the window with a URL other than about:blank.
You can hide the location bar by change the setting dom.disable_window_open_feature.location to true in about:config and then hide the address bar by passing location=false in window.open.
But if you do, then the opener's URL will be prepended to the title bar.
You'll probably have to live with this and be grateful that phishing is that much harder. ;-) Or, if you can make a compelling case for why you should be able to alter or blank the location: (1) add it to your question and (2) open a bug or feature request with Mozilla.
Workaround:
You can set your script to also fire on about:blank, and then have GM make the page from the blank instance, not the opening instance. See this answer for an almost identical scenario/solution.
Be sure to open the window with an explicit about:blank, like so:
var destWindow = window.open("about:blank", "title", null);
We are use window.open for open popup. But then we want find it and close. Unfortunately we can`t save this popup handle to variable.
P.S. How get list of all windows?
This should work:
var wh = window.open(..)
wh is the handle to the popup window.
If you have control over the page that loads the script, you could do something like this. Warning: this is a really scary and generally bad thing to do:
<script>
var windowHandles = {};
(function() {
var realOpen = window.open;
window.open = function(url, name, features) {
windowHandles[name] = realOpen(url, name, features);
};
})();
</script>
That will build an object (windowHandles) in which the handles for each opened window will be saved.
Put that script in your page before the script that opens the other window is loaded.
I found not perfect solution, but it work.
win = window.open(null, 'Window1');
This code search search window with this name and return handler, but if window is closed it open empty popup.
I Think this is temporary solution
I don't like this solution. Fixing the script to give you a handle would be a better bet.
<button onclick="go()">Go</button>
<button onclick="stop()">Stop</button>
<script type="text/javascript">
function go() {
// Existing function. It opens a window with a name.
window.open('http://google.com', 'test', 'width=300,height=300');
}
var foo;
function stop() {
// Open a new window with the same name. It replaces the existing window.
// Since it opens a local document, the Same Origin Policy does not apply.
// ... and we can capture its return value to grab a handle on an existing
// window
foo = window.open('black-local-page.html', 'test', 'width=300,height=300');
// Give the local page time to load
setTimeout(continue_stopping, 500);
}
function continue_stopping() {
// Call window.open() on the window
foo.close();
}
</script>