Embed pdf in Electron app with no toolbar - pdf

I must be missing something very obvious, but after several hours on SO and in the electron docs trying different things, I've not found the right solution.
For an electron app, I have 4 pdfs: 3 are going to be packaged with the electron app, 1 will come from an external website. I need to be able to display each of them at full-screen, with no toolbars or other "fluff". Each is exactly 1 "screen" in size, and this is for a VERY restricted audience so I can guarantee the viewing conditions/technology used. In terms of the needed functionality, these pdfs could just be giant images. However. Due to Reasons(TM) I cannot convert them to any other (easier to use) format.
I am currently using a BrowserWindow, and it works 80%. I can see the pdf just fine, but it's zoomed and still has a toolbar. (This will be displayed in portrait orientation, hence the odd dimensions)
$('#btn_0-0').on('click', function(e) {
e.stopPropagation()
openPDF("./app/assets/docs/TreatmentLandscape.pdf")
})
function openPDF(filePath) {
let pdfWindow = new electron.remote.BrowserWindow({
width: 1080,
height: 1920,
webPreferences: {
plugins: true
}
});
pdfWindow.loadFile(filePath)
pdfWindow.setMenu(null);
pdfWindow.on('closed', function() {
pdfWindow = null
})
}
tl;dr Another person looking for how to do frameless embedded pdfs in electron. Help :(

Related

How to use 3rd party camera app with Ionic React Capacitor

Well the point is the following:
import {
Camera,
CameraResultType,
CameraSource,
Photo,
} from "#capacitor/camera";
export function usePhotoGallery() {
// import { usePhotoGallery } from "../hooks/usePhotoGallery"; per usarlo in esterna
const scatta = async () => {
const cameraPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100,
});
};
return {
scatta,
};
}
With this pretty basic code just calls the default camera and makes it take a shot.
It's working fine no problem. The issue comes in, by my case, by the fact that i have a custom ROM with no pre-installed camera. So no default camera. I know pretty much no one would have my issue. But I'd like to cover those 0.1% of user that will have this problem.
So, finally, how can I can use a 3rd party camera app? Or just create one if it's better.
For example I can take photos from Whatsapp, Instagram, Snapchat ecc. I guess cuz they have their own camera. So the point basically is:
How can I make the user select the app he prefers for thake the shot (like the pop-up that ask "open with *choiches*.."
If i can't do the previous option, then how can I do my own camera?
Sorry for my probably disgusting english

How can I render multiple URL's into a single PDF

I'm attempting to open a series of URL's to render the output, then combine into a single PDF using PhantomJS, but I cannot find any documentation on how to do this. I'm just using trial and error, but not getting anywhere - hoping somebody knows how to do this.
I'm not completely set on PhantomJS, so if you know of a better command line, node or JAVA tool that would be better, I'm all ears (or eyes in this case).
Here is the code I have that renders a single page. I've tried replicating the open/render, but it always overwrites the PDF instead of appending to it.
var page = require('webpage').create(),
system = require('system'),
fs = require('fs'),
pages = {
page1: 'http://localhost/test1.html',
page2: 'http://localhost/test2.html'
};
page.paperSize = {
format: 'A4',
orientation: 'portrait',
};
page.settings.dpi = "96";
// this renders a single page and overwrites the existing PDF or creates a new one
page.open('pages.page1', function() {
setTimeout(function() {
page.render('capture.pdf');
phantom.exit();
}, 5000);
});
PhantomJS renders one web page into one PDF file, so if you can merge several URLs into one html file you could open it in PhantomJS and make a PDF.
But it would be simpler to make several PDFs and then merge them into one with something like pdfkt at the end of the script, launching merge command from PhantomJS child module

How can I screenshot the full height of a mobile form factor?

When testing mobile form factors, Chrome screenshots just the visible window. I'm fine with that being the standard and expected behaviour. However, I additionally want to capture the full scrolled height of the page so I can inspect the rendering of the entire page.
I thought the simplest solution was to set the chrome window height to be a sufficiently large value, and job done. However, the Chrome window height seems bound by my physical screen height, ie. I set it to 5,000 with browser.manage().window().setSize(375,5000);, but it only resizes to a height of 1,200.
I already know [According to the WebDriver specification][1], the [takeScreenshot() function][2] is not supposed to capture the entire page, but should make a screenshot of the visible area only.
OP EDIT: I went with the final option below which I've labelled "Working solution!!"
Below are the different grouped by type strategies to solve the problem.
Scroll, take screenshot, append
Quoting the author of the screenshot system at the CrossBrowserTesting.com:
As the author of the screenshot system for CrossBrowserTesting.com, I can tell you that the only way we've been able to get full page screenshots consistently and reliably across browsers is to scroll, capture, and append images.
Here is a sample working implementation of scrolling and taking visible area screenshots using cnn.com as an example target. Using scrollHeight, clientHeight and scrollTop to determine where we are on a vertical scroll position and how much more to scroll down. Since we are dealing with promises in a loop, we have to make a recursive function with a "we are at the bottom" base condition:
var fs = require('fs'),
Utils = {
screenShotDirectory: '',
writeScreenShot: function (data, filename) {
var stream = fs.createWriteStream(this.screenShotDirectory + filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
},
getSizes: function () {
return browser.executeScript("return {scrollHeight: document.body.scrollHeight, clientHeight: document.body.clientHeight, scrollTop: document.body.scrollTop};");
},
scrollToBottom: function (height, index) {
var self = this;
self.getSizes().then(function (data) {
// continue only if we are not at the bottom of the page
if (data.scrollTop + data.clientHeight < data.scrollHeight) {
browser.executeScript("window.scrollTo(0, arguments[0]);", height).then(function () {
browser.takeScreenshot().then(function (png) {
self.writeScreenShot(png, "test" + index + ".png");
});
});
self.scrollToBottom(height + data.clientHeight, index + 1);
}
});
}
};
describe("Scrolling and saving screenshots", function () {
beforeEach(function () {
browser.ignoreSynchronization = true;
browser.get("http://www.cnn.com/");
});
it("should capture an entire page", function () {
Utils.getSizes().then(function (data) {
Utils.scrollToBottom(data.clientHeight * 2, 1);
});
});
});
It would produce multiple test<index>.png images that you can then glue together.
To concatenate images in a "single column image", you may, for instance, use the GraphicsMagick Image Processing System through the gm nodejs module. The .montage() method with the concatenate option in the 1x mode would be helpful. Sample code:
var gm = require('gm');
Utils.getSizes().then(function (data) {
var index = Utils.scrollToBottom(data.clientHeight * 2, 1);
var op = gm();
for (var i = 1; i <= index; i++) {
op = op.in("test" + i + ".png");
}
op = op.montage().mode("concatenate").tile("1x");
op.write('output.png', function (err) {
if (err) console.log(err);
});
});
Change the Browser
In Chrome, you would always get only the visible area on the resulting screenshot, here is the relevant chromedriver issue with a lot of information about the issue and multiple workarounds:
ChromeDriver2 take screenshot is not full page
Somewhat surprisingly, it should though work in Firefox - switch to it if possible:
Chrome screenshots that take up the entire screen are not like Firefox's. Firefox will capture the entire screen, even parts of it that are not currently viewable. Chrome will not!
Tweak the Screen Size
Another option would be to use services like BrowserStack or SauceLabs to start your tests on a specific platform in a specific browser and, using a specific large enough resolution. Protractor supports Sauce Labs and BrowserStack out-of-the-box.
Example configuration for BrowserStack:
exports.config: {
browserstackUser: "user",
browserstackKey: "key",
capabilities: {
'browserstack.local': true,
'browserstack.debug': true,
browserName: "Chrome",
os: "Windows",
os_version: "8",
resolution: "2048x1536"
},
}
Then, maximize the browser window (inside onPrepare(), for instance):
browser.driver.manage().window().maximize();
And make a screenshot.
Working solution!!!
Another option could be to run tests in a Virtual Display. I you would follow this blogpost and use Xvfb, when you will run the Xvfb server, you may specify the resolution:
/usr/bin/Xvfb :99 -ac -screen 0 2048x6000x24 &
Also see related information on this topic here:
AngularJS Headless End to End Testing With Protractor and Selenium
What is a good headless browser to run with protractor?
You may also use the docker-selenium solution which allows to configure the screen size.

Javascript Style Sheet in Titanium mobile

I'm a learning mobile development using Titanium Mobile framework.
I am facing a problem related to application of javascript style sheet.
When I name my jss file same as the js file, to which the style is to be applied, it works fine. But if I name it something else, it don't work. Can anybody tell me a solution. Following is my code sample.
// app.js
var win = Titanium.UI.createWindow({ backgroundColor : '#fff' });
win.add( Ti.UI.createButton({ title : 'Button A' }) );
win.open();
// app.jss, works fine
button { backgroundImage: 'grdadient_img.png'; }
// button_style.jss, don't work
button { backgroundImage: 'grdadient_img.png'; }
I never had much success using more than one JSS file. And if you follow Nandu's links you'll see that it's not really documented very well, likely to be removed from Titanium at some point. I expect that Titanium's Alloy will kill off JSS too.
If you don't want to use JSS (or Alloy yet), there is a neat way to centralise your styles using commonJS modules and optionally underscore.js e.g.
theme.js
var theme = {
tableLabel : {
color : '#3285C7',
backgroundColor : 'transparent',
inactiveColor : '#AAAAAA'
}
}
module.exports = theme;
to use
var theme = require('ui/common/Theme');
...
var myLabel = Ti.UI.createLabel(_.extend({}, theme.tableLabel, {
top : 5,
height : Ti.UI.SIZE,
width : Ti.UI.FILL,
text : "Hello world",
}));
I use _extend to take the settings from the theme and add instance specific settings like size, position etc. Don't forget the first empty object literal in the call to `_.extend()
See http://underscorejs.org/#extend
Ammar, please refer the following links. Hope it will help you
1.How to use jss correctly
2.How Does .jss feature really works in Titanium mobile SDK

sencha touch - custom html template ported from another framework

Previous attempt at this app was done in jqtouch and this effect worked perfectly. Im having a really hard time wrapping my head on how best to do this with sencha touch.
My situation is best described in this image
This is just one item that should populate a carousel so reusing it with different data is paramount (no hard coded html).
thank you
Finally solved it thought I should update it here
Ext.define('mobuy.view.myCarousel', {
extend: 'Ext.carousel.Carousel',
alias: 'widget.myCarousel',
config: {
myitems: 0,
},
updateMyItems: function(newItem) {
var localCarouselItems = [];
Ext.each(newItems, function(item){
localCarouselItems.push({
xtype:'localItem',
data:item.data
});
});
this.setItems(localCarouselItems);
this.setActiveItem(0);
}
})
what this does is basically create an array of new items of type localItem from the store when one calls setMyItems and sets the data (to be used with xtemplate or whatever) for each of those items.
If anybody needs more details please ask and I'll update my answer.