I am making a chrome extension and wanted to add an option to resize the browser window.
I know I can't resize the window with normal JS.(window.resizeTo(600, 600); etc. won't work)
But with extension it's possible. For example with this tool you can resize the window. Problem is that I don't know how.
Also seems possible to open a new tab with desired sizes but it won't open a normal window but a tab.(Like ads)
Does anyone know how to achieve this?
You can try the window API for chrome extensions
chrome.windows.getCurrent(function(wind) {
alert(wind.id);
var maxWidth = window.screen.availWidth;
var maxHeight = window.screen.availHeight;
var updateInfo = {
left: 0, //change those to whatever you like
top: 0,
width: maxWidth,
height: maxHeight
};
chrome.windows.update(wind.id, updateInfo);});
Found an answer:
We need 2 js files. background.js and main.js(content js file, name can be anything).
main.js doesn't have access to extension apis, tabs, background stuff etc. So we will send a message to background.js from our main.js file and get that message in background.js file and execute what we want.
main.js:
chrome.runtime.sendMessage(
{
action: "resizeWindow",
},
function (createdWindow) {
console.log("Window Resize");
}
);
background.js:
//Windows resize
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request && request.action === "resizeWindow") {
chrome.windows.getCurrent(function (window) {
var updateInfo = {
width: 1200,
height: 710,
};
(updateInfo.state = "normal"), chrome.windows.update(window.id, updateInfo);
});
}
});
Note that we need updateInfo.state = "normal".
Related
After my dashboard initializes and is fully loaded, I need to get the window height of the embed inside the iframe. Ideally, I'd like to get innerHeight inside of onFirstInteractive, but am unable to do so.
function initViz() {
var containerDiv = document.getElementById("vizContainer");
var url = "http://public.tableau.com/views/RegionalSampleWorkbook/Storms";
var options = {
onFirstInteractive: function() {
// How do I get the height of the rendered contents?
}
};
var viz = new tableau.Viz(containerDiv, url, options);
}
Subscribe to the VIZ_RESIZE event, it provides the new dimensions of the iframe on initialization and resize:
viz.addEventListener(tableau.TableauEventName.VIZ_RESIZE, function(event) {
console.log(event.getAvailableSize());
});
Which gives the following:
When the iframe appears like this:
If you absolutely want to retrieve the information in onFirstInteractive, you can do this:
onFirstInteractive: function(viz) {
const iframeStyle = viz.$1._impl.$1h.style;
const { height, width } = iframeStyle;
console.log({ height, width });
}
But it's a little bit hacky because this solution uses properties that are not supposed to be public, so this kind of code may break on future Tableau JS library updates.
I'm trying to download an image from a WebPage, which is returned by a JavaScript (using html2canvas) immediately after calling it. Therefore I'm using the library HTMLUnit, but I haven't been successful until now.
Unfortunately only a faulty png-File is downloaded, which has around 140kb. It can't be opened by Windows (e.g. paint or preview).
Code-Snippet for my HTML-Page (executed immediately after div-element #div is loaded:
function saveMap() {
var element = $("#div");
html2canvas(element, {
useCORS: true,
onrendered: function(canvas) {
var dataUrl= canvas.toDataURL("image/png");
var a = $("<a>")
.attr("href", dataUrl)
.attr("download", "test.png")
.appendTo("body");
a[0].click();
a.remove();
}
});
}
Java-Code trying to download the returned png-File:
WebClient webClient = new WebClient(BrowserVersion.CHROME);
try {
HtmlPage page1 = webClient.getPage( new URI("file:///D:/path/to/page/sample.html").toURL() );
webClient.waitForBackgroundJavaScript(5000);
InputStream is = page1.getWebResponse().getContentAsStream();
File f = new File("test.png");
OutputStream os = new FileOutputStream(f);
byte[] bytes = new byte[2048];
int b = 0;
while ((b = is.read()) != -1)
{
os.write(bytes, 0, b);
}
os.close();
is.close();
} catch (FailingHttpStatusCodeException | IOException | URISyntaxException e) {
e.printStackTrace();
}
Full HTML-Page:
<!DOCTYPE html>
<html>
<head>
<style>
html, body, #div {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="html2canvas.js"></script>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
</head>
<body>
<div id="div"></div>
<script>
// Some init stuff for div and after completion the following:
saveMap();
function saveMap() {
var element = $("#div");
html2canvas(element, {
useCORS: true,
onrendered: function(canvas) {
var dataUrl= canvas.toDataURL("image/png");
var a = $("<a>")
.attr("href", dataUrl)
.attr("download", "test.png")
.appendTo("body");
a[0].click();
a.remove();
}
});
}
</script>
</body>
</html>
Thanks for the code. Have already done some tests with the samples available on the html2canvas web page. There is bug in the current version of HtmlUnit that stops the javascript from working.
I think i have done a fix also, but sourceforge is down at the moment. If they are back i will commit the fix and prepare a new snapshot. Will inform you and also have a look at your sample.
BTW: Do not expect nice screenshots from this. HtmlUnit is a headless browser and most of the layout functions are doing only a basic job. But you are welcome to provide better implementations.
Your code works (with some fixes) with the latest snapshot.
But to get reasonable results you have to provide a width and height for the result. I guess there is some layouting in HtmlUnit that returns otherwise 1x1 as result size. If this is a problem for you might have a look inside the code and try to point to the problematic place.
html2canvas(element, {
useCORS: true,
width: 300,
height: 300,
onrendered: function(canvas) {
Now to your java code
HtmlPage page1 = webClient.getPage( new URI("file:///D:/path/to/page/sample.html").toURL() );
webClient.waitForBackgroundJavaScript(5000);
The tricky part here is the async execution of the rendering inside your browser. From HtmlUnit point of view the browsers will, after the loading of the page was done, replace the content of the current window with the png image. Andd you have to deal with this in your code. Because there is a replace your page1 is still the old page returned (sync).
After the wait you have to reget the current content to have the png in hands
Page image = webClient.getCurrentWindow().getEnclosedPage();
InputStream is = image.getWebResponse().getContentAsStream();
And finally there is a small issue with your image writing code
Instead of
while ((b = is.read()) != -1)
you have to write
while ((b = is.read(bytes)) != -1)
Otherwise you will end up with a file of null bytes.
Hope that helps.
I am have been able to open a new window when i click a button, however, its a new pop up window. How can I have the new window open up in place of the main window?
var app = require('app')
var BrowserWindow = require('browser-window')
var ipc = require('ipc')
app.on('ready', function () {
var mainWindow = new BrowserWindow ({
width: 800,
height: 600
})
mainWindow.loadURL('file://' + __dirname + '/main.html')
//mainWindow.openDevTools() //opens inspect console
var prefsWindow = new BrowserWindow ({
width: 400,
height: 400,
show: false
})
prefsWindow.loadURL('file://' + __dirname + '/prefs.html')
With the code above, a new window pops up. Ive attached a screenshot to show what I mean.
popup window
Instead of that popup window, i want 'prefs' to replace the main window (and other options to replace the main window once added).
Instead of creating a new window, just load the prefs.html into the mainWindow. Your old content (main.html) will get replaced without additional windows opening.
When the respective button is placed inside the main.html you will need to apply this loading via the ipc remote module.
Following this SO answer for Electron 0.35.0 and above:
// In main process.
const ipcMain = require('electron').ipcMain;
// in main process, outside of app.on:
ipc.on('load-page', (event, arg) => {
mainWindow.loadURL(arg);
});
// In renderer process (web page).
const ipc = require('electron').ipcRenderer;
Loading the new page can then be performed as follows:
ipc.send('load-page', 'file://' + __dirname + '/prefs.html');
In case anyone interested, this is what I did.
assuming I have login form and after signing in I wanted to show the main window where things will happen.
setup your index.js
const electron = require('electron');
const url = require('url');
const path = require('path');
const { app, BrowserWindow } = electron;
let loginWindow;
var mainIndex = '../../index.html'; //the login window
var directoryHtml = '../html/'; //directory of where my html file is, the main window is here except the login window
var iconPath = '../../images/logo.png'; //replace with your own logo
let { ipcMain } = electron;
var newWindow = null;
app.on('ready', function () {
loginWindow = new BrowserWindow({//1. create new Window
height: 600, width: 450,
minHeight: 600, minWidth: 450, //set the minimum height and width
icon: __dirname + iconPath,
frame: false, //I had my own style of title bar, so I don't want to show the default
backgroundColor: '#68b7ad', //I had to set back color to window in case the white screen show up
show: false //to prevent the white screen when loading the window, lets not show it first
});
loginWindow.loadURL(url.format({ //2. Load HTML into Window
pathname: path.join(__dirname, mainIndex),
protocol: 'file',
slashes: true
}));
loginWindow.once('ready-to-show', () => {
loginWindow.show() //to prevent the white screen when loading the window, lets show it when it is ready
})
});
//dynamically resize window when this function is called
ipcMain.on('resize', function (e, x, y) {
loginWindow.setSize(x, y);
});
/** start of showing new window and close the login window **/
ipcMain.on('newWindow', function (e, filenName) {
if(newWindow){
newWindow.focus(); //focus to new window
return;
}
newWindow = new BrowserWindow({//1. create new Window
height: 600, width: 800,
minHeight: 600, minWidth: 800,
icon: __dirname + iconPath,
frame: false,
backgroundColor: '#68b7ad',
show: false
});
newWindow.loadURL(url.format({ //2. Load HTML into new Window
pathname: path.join(__dirname, directoryHtml + filenName),
protocol: 'file',
slashes: true
}));
newWindow.once('ready-to-show', () => { //when the new window is ready, show it up
newWindow.show()
})
newWindow.on('closed', function() { //set new window to null when we're done
newWindow = null
})
loginWindow.close(); //close the login window(the first window)
});
/** end of showing new window and closing the old one **/
app.on('closed', function () {
loginWindow = null;
});
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (loginWindow === null) {
createWindow()
}
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Login Window</title>
</head>
<body>
<h1>Login</h1>
<!-- . . . . -->
<button id="btn-login" onclick="loginNow()"></button>
<!-- . . . . -->
<script>
function loginNow(){
//.....
//assuming the authentication is valid, we want to show now the new window which will be our main window
const { ipcRenderer } = require('electron'); //require electron
//using ipcRenderer, let's call the function in index.js where the function name is `newWindow`,
//the `main.html` is the new html file I want to show, use your own.
ipcRenderer.send('newWindow','main.html');
}
</script>
</body>
</html>
I don't if this is the right way to do it, and I don't know the disadvantage of doing it like this but I hope none. hope this help someone.
You have a few options.
You could just call prefsWindow.focus() to ensure the second window is on top of the first.
You could hide or close the main window with mainWindow.hide() or mainWindow.destroy(), leaving only the second window open. Then reopen it when your done.
Or instead of having two windows, you could just load your prefs page into the first window, and when done back to the main page.
I had faced a similar issue when creating an application that foremost required authentication before accessing the actual content. So the first and main page of the application was a login form. After the login was successful, a new page should load instead where the actual content was suppossed to be. To do so, i have done the following:
In main.js or index.js how you'd name it, instead of loading the second window at the start and then show it, i load it inside an IPC event listener. So it loads the page when the IPC listener receives a certain event.
const {ipcMain} = require('electron');
ipcMain.on('login', (event, arg) => {
loginPage.loadURL(url.format({
pathname: path.join(__dirname, 'mainpage.html'),
protocol: 'file',
slashes: true
}));
});
Note, that loginPage is my main window that gets created on app.on() and mainpage is the second page that gets created after a successful login.
Then in my loginPage.html, after i verify the login, if it's successful i send that IPC renderer message back to the main process. Which is fairly simple to do:
var ipc = require('electron').ipcRenderer;
ipc.send('login', 'an-argument');
Above method should work. I am just a beginner so i cannot say if it's the best way to do this or if it has any unwanted implication that are not immediately seen, but it's worked out for me so you might as well give it a try.
I was fighting the same issue as you did until I found a simple solution.
Here's the JS code:
const electron = require('electron');
let rootPath = "src/Page/index.html" //Path to the html file
LoadNewWindowInCurrent(rootPath); //Opens new html file in current window
//Here's the ready function for you to use
function LoadNewWindowInCurrent (PathToHtml){
let localWindow = electron.remote.getCurrentWindow();
localWindow.LoadFile(PathToHtml);
}
I've got a problem: the chrome.experimental.offscreenTabs.create worked well, but the toDataUrl method produced an image with a height of 1 pixel. I've tried my best, but the image produced by toDataUrl does not show the size as I specified. How can this problem be solved?
Here is my code:
chrome.experimental.offscreenTabs.create({ url: "http:/www.baidu.com" }, function(offscreenTab) {
// console.log(offscreenTab);
chrome.experimental.offscreenTabs.toDataUrl(offscreenTab.id, { format: "png" }, function(imgUrl) {
$("#container").html("<img src='" + imgUrl + "' />");
});
});
The offscreenTabs API is experimental. The solution below has successfully been tested in Chromium 20.0.1132.57 (Linux), but that doesn't mean that the code still works in later versions.
This answer is a follow-up to How to use the experimental offscreenTab API?
The callback function of chrome.experimental.offscreenTabs.create is called when the tab is created. Tests using the chrome.webRequest API and the UNIX netcat command showed that the callback can be fired before the server responds. Hence, it's unlikely that a callback is triggered after the page is rendered.
My demo extension consists of 5 files. Their role is briefly explained:
manifest.json - The required glue for the extension (see documentation).
sayhello.js - A content script which notifies the background page. This helper is necessary, because the chrome.tabs and chrome.webRequest are useless: The event listeners of chrome.tabs are never triggered for offscreen tabs, and the event listeners of chrome.webRequest are triggered before the page is rendered.
background.js - A background page to receive the message from the content script. chrome.extension.getViews() is used to locate the view which launches the offscreen tab.
options.html - The visible view which launches offscreen tabs. (The background page cannot launch an offscreen tab).
options.js - When manifest version 2 is active, inline scripts are not executed. The script must be placed in an external file, and loaded using <script src>.
I've uploaded the extension to http://rob.lekensteyn.nl/offscreentabs.zip same file, crx extension: CRX. Don't forget to enable the experimental permission at chrome://flags, if you want to test it.
manifest.json
{
"name": "OffscreenTabs API test",
"version": "1.0",
"description": "offscreenTabs demo - See https://stackoverflow.com/q/11606135",
"manifest_version": 2,
"permissions": ["experimental", "<all_urls>"],
"options_page": "options.html",
"background": {"scripts": ["background.js"] },
"content_scripts": [{
"js": ["sayhello.js"],
"matches": ["<all_urls>"]
}]
}
sayhello.js
chrome.extension.sendMessage("Hello"); // Yup, that's it
background.js
chrome.extension.onMessage.addListener(function(message, sender) {
if (message === "Hello" && sender && sender.tab) {
// Message received from content script, pass information to a view
// within our extension, which processes offscreenTabs
chrome.extension.getViews({type:"tab"}).forEach(function(_window) {
if (_window.checkTab) _window.checkTab(sender.tab.id);
});
}
});
options.html
<!DOCTYPE html>
<head>
<meta charset="utf8">
<title>offscreenTabs test</title>
<script src="options.js"></script>
</head>
<body>
Enter an URL and press <kbd>Enter</kbd>.<br>
<input type="url" size="100" id="url" value="https://stackoverflow.com/users/938089/rob-w">
<img id="lastImg">
</body>
</html>
options.js
"use strict";
var collection = [];
// This function is called by the background (via the content script)
// If the tabId is recognised, take a screenshot
function checkTab(tabId) {
var index = collection.indexOf(tabId);
if (index !== -1) {
collection.splice(index, 1); // Remove tabId
toDataUrl(tabId); // Take screenshot
}
}
function create(url, width, height) {
var createProperties = {url: url};
if (width) createProperties.width = width;
if (height) createProperties.height = height;
// Create offscreen tab
chrome.experimental.offscreenTabs.create(createProperties, function(offscreenTab) {
console.log("Created " + offscreenTab.id, offscreenTab);
collection.push(offscreenTab.id);
});
}
function toDataUrl(offscreenTabId, options) {
chrome.experimental.offscreenTabs.toDataUrl(offscreenTabId, options, function(dataUrl) {
document.getElementById('lastImg').src = dataUrl;
});
}
document.addEventListener('DOMContentLoaded', function() {
// "Press Enter to load the offscreen tab and take a screenshot"
document.getElementById('url').onkeyup = function(ev) {
if (ev.keyCode == 13)
create(this.value);
};
});
hi how to use javascriptscript to open a new window and then closing the current window..
currently, i can only open a new window, however my current window is still left open.
Code:
function newfunction()
{
window.open("index.html", "myWindow", "status = 1, height = 300, width = 300, resizable = 0");
}
Opening a new window and closing the old one sounds very much like changing the current page to me. Use location.href = 'newurl'.
And if you want to change its size and so on, that can also be done.
window.innerWidth = 300;
window.innerHeight = 300;
location.href = 'newurl';
use like you said window.open and then in the main window window.close(). But if you use like this, the browser will ask you "This website wants to close this window blabla".
add window.opener.close();
function newfunction()
{
window.open("index.html", "myWindow", "status = 1, height = 300, width = 300, resizable = 0");
window.opener.close();
}
or add this on the index.html file whenever a new window open it will close the parent window
<body onload="window.opener.close()">
Here is the code you need:
function newfunction()
{
window.open("index.html", "myWindow", "status = 1, height = 300, width = 300, resizable = 0");
window.close();
}
This will work only if the current window was opened via script as well, otherwise IE show warning dialog and other browsers might simply ignore it.