printing support on chrome packaged apps - google-chrome

I can't seem to find any example of window.print() support in chrome packaged apps - can someone please post an example?
I'm using this
function clickHandler(e) {
window.print();
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').addEventListener('click', clickHandler);
});
from "Hello World!" sample platform app, but I can't seem to get it working.
is there a special permission settings I should use?
Thanks!

Yes, window.print() works in Chrome Apps. You can find a sample in the official samples repo.
It is as simple as calling window.print() in any DOM window of your app:
// prints the content of the current window:
window.print();
// prints the content of another AppWindow:
anotherAppWindow.contentWindow.print()
AppWindow is the Chrome Apps object that encapsulates and extends the actual DOM window with app capabilities. This object can be obtained by either:
saving the parameter from the callback of chrome.app.window.create
calling chrome.app.window.current() on any code running in the context of the desired window

Related

How to determine why an alert dialog was displayed by Chrome?

I am trying to fix a bug in a Chrome extension. When the extension is installed an alert dialog containing the message "undefined" will be displayed seemingly at random. This does not happen when the extension is not installed.
There is not one call to alert, confirm, or prompt in the extension source code. How do I find out why the alert dialog is being displayed?
I have attempted adding the following code to one of the background scripts and to one of the content scripts.
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace();
return originalWindowAlert.apply(window, arguments);
}
I have confirmed that this technique works when used in a webpage, but it is not working for the extension.
I have also built Chromium from source code and I am able to reproduce it but so far I have not been able to figure out how to determine the origin of the alert dialog. I have set a breakpoint in the RenderFrameHostImpl::RunModalAlertDialog function but I see no way to determine what caused the breakpoint to be hit.
I am getting desperate.
I asked this question on the Chromium Extensions Google Group. I got the following very useful response from Scott Fortmann-Roe.
If you do the following in a content script:
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace();
return originalWindowAlert.apply(window, arguments);
}
I don't believe it will actually intercept alerts triggered by the page as you are overriding the content script's window.alert method which is different from the page's method (content script JS is isolated from page JS).
To modify the page's alert method you'll probably need to inject a script tag into the page. E.g. something along these lines in the content script:
let script = document.createElement('script');
script.textContent = `
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace()
return originalWindowAlert.apply(window, arguments);
} `;
document.body.appendChild(script);

Google Chrome frameless (like kiosk)

I want know if is it possible to make Google Chrome behave like a kiosk (without a frame or controls) but not in full screen, like the next mock picture:
My solution in Electron:
var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is GCed.
var mainWindow = null;
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600, frame:false});
// and load the index.html of the app.
mainWindow.loadURL('http://www.google.com/');
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
});
I do not think that it's possible to make Chrome itself behave that way, but a Chrome App (not an extension) can do this.
This is an option in window creation:
chrome.app.window.create("app.html", {
frame: "none"
});
Note that you will have to provide your own controls to close/move the window.
To make it behave like a browser, you'll need to embed a <webview> element. See also a browser app example.
However, note that Chrome Apps are being deprecated.
You should consider using a similar platform, like Electron or NW.js, to build your own "mini-browser" for your purpose.

Adding API's to chromium build in Electron framework

I would like to write custom functions in Window API in chromium source code. So how do we do it?
In case of doubts about window API here's a link to what I mean click here. I would like to have custom property functions analogus to those shown in the link.
It's for a github electron project.
Well after a week of searching I finally found the solution. Thanks to a pull request by magicae#github.
You need to look create your custom function in
electron/atom/browser/api/lib/atom_api_web_contents.cc
as say
bool WebContents::GetOkOk() {
return true;
}
And define the same in it'h header file
electron/atom/browser/api/lib/atom_api_web_contents.h
as
bool GetOkOk();
Lastly you need to export the function through the webContents method located in
electron/atom/renderer/lib/web-view/web-view.js
as
/* Public-facing API methods. - modified by Akshay Thakare */
methods = ['getOk','getURL', ... ];
And you are good to go.
Finally after you compile your electron app,
in the main.js file add,
console.log(mainWindow.webContents.getOk());
and your done.
As JS is prototype oriented, you could simply extend the BrowserWindow API
var BrowserWindow = require('electron').BrowserWindow; // main process
var BrowserWindow = require('electron').remote.BrowserWindow; // renderer process
BrowserWindow.foo = function() {
console.log('foo');
}
Not sure if you're looking for someting more specific, but I'm not sure you can extend it with heavy impacts on the system, could you explain exactly what you are trying to do ?

Chrome content_script: How to wait for jQuery

I'm writing a small Chrome extension that would have a content_script.
It would run on a single domain, I'm trying to improve a site a bit.
I want to use jQuery in my content script, but the site also uses jQuery, so I cannot simply add jQuery to my extension's content_script array.
My content_script will
"run_at": "document_end"
but jQuery is not yet loaded. It's not loaded on document_idle either.
So I have to wait for it.
How do I do that?
I've tried doing this:
(function() {
var i = setInterval(function () {
console.log(typeof jQuery + " " + i);
if (typeof jQuery != "undefined") {
console.log("jQuery loaded");
clearInterval(i);
} else {
console.log("jQuery not loaded");
}
}, 200);
})();
But for some reason typeof jQuery is always undefined within that loop.
If I manually clearInterval, and check typeof jQuery I properly get "function".
(chrome inspector console)
Any ideas?
EDIT:
content_scripts are special:
Content scripts are JavaScript files that run in the context of web
pages. By using the standard Document Object Model (DOM), they can
read details of the web pages the browser visits, or make changes to
them.
I cannot simply add jQuery to my extension's content_script array.
You can and should. Extension variable space is sandboxed, so content scripts cannot access variables from parent's page and vice versa.

How do I access the popup page DOM from bg page in Chrome extension?

In Google Chrome's extension developer section, it says
The HTML pages inside an extension
have complete access to each other's
DOMs, and they can invoke functions on
each other. ... The popup's contents
are a web page defined by an HTML file
(popup.html). The popup doesn't need
to duplicate code that's in the
background page (background.html)
because the popup can invoke functions
on the background page
I've loaded and tested jQuery, and can access DOM elements in background.html with jQuery, but I cannot figure out how to get access to DOM elements in popup.html from background.html.
can you discuss why you would want to do that? A background page is a page that lives forever for the life time of your extension. While the popup page only lives when you click on the popup.
In my opinion, it should be refactored the other way around, your popup should request something from the background page. You just do this in the popup to access the background page:
chrome.extension.getBackgroundPage()
But if you insist, you can use simple communication with extension pages with sendRequest() and onRequest. Perhaps you can use chrome.extension.getViews
I understand why you want to do this as I have run into the problem myself.
The easiest thing I could think of was using Google's method of a callback - the sendRequest and onRequest methods work as well, but I find them to be clunky and less straightforward.
Popup.js
chrome.extension.getBackgroundPage().doMethod(function(params)
{
// Work with modified params
// Use local variables
});
Background.html
function doMethod(callback)
{
if(callback)
{
// Create/modify params if needed
var params;
// Invoke the callback
callback(params);
}
}
As other answers mention, you can call background.js functions from popup.js like so:
var _background = chrome.extension.getBackgroundPage();
_background.backgroundJsFunction();
But to access popup.js or popup.html from background.js, you're supposed to use the messages architecture like so:
// in background.js
chrome.runtime.sendMessage( { property: value } );
// in popup.js
chrome.runtime.onMessage.addListener(handleBackgroundMessages);
function handleBackgroundMessages(message)
{
if (message.property === value)
// do stuff
}
However, it seems that you can synchronously access popup.js from background.js, just like you can synchronously access the other way around. chrome.extension.getViews can get you the popup window object, and you can use that to call functions, access variables, and access the DOM.
var _popup = chrome.extension.getViews( { type: 'popup' } )[0];
_popup.popupJsFunction();
_popup.document.getElementById('element');
_popup.document.title = 'poop'
Note that getViews() will return [] if the popup is not open, so you have to handle that.
I'm not sure why no one else mentioned this. Perhaps there's some pitfalls or bad practices to this that I've overlooked? But in my limited testing in my own extension, it seems to work.