Enable pinch to zoom inside iframe - Ionic 2 AngularJS 2 - html

I added zooming="true" inside the tag but when the page is loaded I cannot zoom to increase or decrease the view. I've also set webkitallowfullscreen mozallowfullscreen allowfullscreen to scale the page in order to fit the device screen but nothing changed and the page is still cut.
To explain this concept a little better I take for example Android native apps. Now, if you want to load a page from the web you use a WebView and the result is exactly like using an iframe on Ionic. But on android things become simpler regarding customization:
webview.getSettings().setBuiltInZoomControls(true);
to enable pinch-to-zoom, and
webview.getSettings().setUseWideViewPort(true);
to fit and scale the web page depending on the size of the (mobile) screen.
Now, using Windows 10 it's not possible for me to build native iOS apps so I have to rely on cross-platform development.
Here's my detail-page:
html:
<ion-content>
<iframe sandbox class="link" frameborder="0" [src]="webPage()" zooming="true" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</ion-content>
scss:
detail-page {
.scroll-content{
padding: 0px ;
}
::-webkit-scrollbar,
*::-webkit-scrollbar {
display: none;
}
iframe.link {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}
}
ts:
webPage() {
return this.sanitizer.bypassSecurityTrustResourceUrl(this.entry.getElementsByTagName('link')[0].textContent);
}
Hope you can help me.
Edit
I added document.getElementsByTagName('iframe').contentWindow.document.body.style = 'zoom:50%'; but I'm getting a Typescript error:
Typescript Error
Property 'contentWindow' does not exist on type 'NodeListOf<HTMLIFrameElement>'.
Here's my whole .ts file:
export class DetailPage {
entry:any = [];
constructor(private sanitizer: DomSanitizer, public nav: NavController, navParams:NavParams) {
console.log('run');
this.nav = nav;
this.entry = navParams.get('selectedEntry');
console.log('My entry is: "'+ this.entry.getElementsByTagName('title')[0].textContent + '"');
document.getElementsByTagName('iframe').contentWindow.document.body.style = 'zoom:50%';
}
webPage() {
return this.sanitizer.bypassSecurityTrustResourceUrl(this.entry.getElementsByTagName('link')[0].textContent);
}
}
Edit 2
After adding id="myframe" inside <iframe> I've also tried with the function ngAfterViewInit() but still no changes there.
ngAfterViewInit() {
var x = document.getElementById("myframe");
var y = (<HTMLIFrameElement> x).contentWindow.document;
y.body.style.zoom = "50%";
}
And in this form too:
ngAfterViewInit() {
var iframe:HTMLIFrameElement = <HTMLIFrameElement>document.getElementById('myframe');
var iWindow = (<HTMLIFrameElement>iframe).contentWindow.document;
iWindow.body.style.zoom = "50%";
}

I think it is not possible to do in a IFrame as that will be a security flaw.
what you are basically doing is trying to access a webpage from your mobile hybrid app (Ionic App in your case).
it must not allow you to run javascript on that webpage, workaround for it will be by disabling web security on that browser or in your case webview (not sure how to do that in mobile but that is manual browser customization so will not work in your scenario).
more explanation on this post
SecurityError: Blocked a frame with origin from accessing a cross-origin frame

You will need to track the gesture and apply the change of zoom to the iframe like this
document.getElementByTagName('iframe').contentWindow.document.body.style = 'zoom:50%';
Here the zoom is set to 50%, but this can be added dynamically using the gesture event values.

Related

#media display-mode: fullscreen does not work on Chrome Mobile

i want to add to my css
the fullscreen check, similar to this below :
#media all and (display-mode: fullscreen) {
body {
background-color: red;
}
}
this example has taken from here:
https://developer.mozilla.org/en-US/docs/Web/CSS/#media/display-mode
I would need it to work on Chrome mobile Android, but as of today, I'm trying but it doesn't work, although it is compatible, on other mobile browsers(Edge or Samsung browser) it works.
Note: to launch Fullscreen on browser i use something like :
function fullScreenMode() {
var doc = window.document;
var docEl = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen();
requestFullScreen.call(docEl);
}
then fullScreenMode() via debug on Chrome:inspect on console,

How do I access the image gallery from a PWA

I need to know how to access the image gallery from a PWA. Currently the PWA will allow me to take pics and upload those on a mobile device but it won't let me access the image gallery and select images. On an actual desktop I can access the image gallery but not from an actual device...I can only access the camera to take photos.
So far I've looked into trying to set my browser to allow access to the image gallery but I don't see a setting on my Chrome browser from my android phone.
Here's the code:
uploadFromFile(event, photoName: string) {
const files = event.target.files;
console.log('Uploading', files);
const file = new Blob([files[0]], { type: 'image/jpeg' });
console.log('file', file);
const { type } = file;
this.imageService.uploadImage(file, photoName, this.currentUser.uid)
.then((url) => {
this.photo0 = url;
console.log('url edit prof', url);
}).catch((error) => {
alert(error.message);
});
}
#capture::file-selector-button {
display: none;
}
#capture {
color: transparent;
}
#capture::before {
content: url("../../../assets/image/SpaghettiPlus2.png");
padding: 140px;
align-items: center;
}
<input type="file" id="capture" accept="image" capture (change)="uploadFromFile($event, 'photo0')" />
It took a while to find this method of uploading pics in a PWA. Using the input for a file picker was the only solution I could find online for allowing PWAs to access pics.
So right now I just want to be able to access the photo gallery on a device in order to upload pics.
The problem is the capture attribute.
According to MDN:
capture was previously a Boolean attribute which, if present, requested that the device's media capture device(s) such as camera or microphone be used instead of requesting a file input.
Also, the value of the accept attribute seems to be wrong (according to MDN). If it doesn't work try accept="image/*" instead.

html video fullscreen mode with typescript

could someone please tell me how to turn on fullscreen mode when using video tag? I am using following typescript:
var vid = <HTMLVideoElement> document.getElementById('video1');
I would like to play video in fullscreen in window.onload event.
It seems typescript does not support requestFullscreen, or other "webkitFullscreen" mode. I search other questions on stackflow, and they seem bit outdated.
You can add those to the interface:
// Add the missing definitions:
interface HTMLVideoElement{
requestFullscreen();
webkitRequestFullscreen();
}
// now the following should work
var vid = <HTMLVideoElement> document.getElementById('video1');
if (vid.requestFullscreen){
vid.requestFullscreen();
}else if (vid.webkitRequestFullscreen){
vid.webkitRequestFullscreen();
}
I tried this but does not work.
I am looking to play fullscreen video from window.onload event. If I add a button on the page and add hook up the code you mentioned, then it works. code Click Me To Go Fullscreen!
Also, IE10 does not seem to support any of these modes. Is that expected?
Opening a video in full screen requires a synchronous user interaction, i.e. the user must click on a button, and only then the click handler can request full screen mode.
Please try this then
var elem = document.getElementById("myvideo");
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
For documentation Document

Touch location misinterpreted on iPad when rescaling an iframe showing a kineticjs canvas

I am building a widget using KineticJS (which is fantastic). It allows the user to drag images around in a canvas.
I can view and use the widget inside an iframe: this works perfectly on all the browsers and devices I have tried.
I can even scale that iframe so the page is responsive. Following another stackoverflow post, I have added the css:
#media screen and (max-width : 768px) {
iframe {
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
-moz-transform: scale(0.85);
-o-transform: scale(0.85);
-webkit-transform: scale(0.85);
}
}
This works well on my Mac.
But on an iPad, although the iframe appears properly scaled, when you try to drag elements around, it seems to think they are in their unscaled positions.
Is there a way I can get this to work on the iPad too? Or do I need to rethink my design (in which case, what design should I use)?
thanks!
Thanks to #irie11's suggestion, I have now implemented this. In the interests of posterity, here is my full approach.
I added some javascript to rescale the canvas when the window changes size:
function scaleCanvasToContainer() {
var container_width = $("#my-containers-parent-id").width();
var scale = 1.0;
if (container_width<target_width) {
scale = container_width/target_width;
}
$("#my-container-id").css("max-height",scale*target_height+"px");
stage.setScale(scale,scale);
stage.setWidth(scale*target_width);
stage.setHeight(scale*target_height);
stage.draw();
drawLines();
}
window.onresize = function(event) {
scaleCanvasToContainer();
}
...
scaleCanvasToContainer();
Note the above also resizes the canvas (i.e. changes its width and height), and for good measure sets the maximum height through css too.
I discovered that when you use context.moveTo() these coordinates are not scaled, so I had to manually scale them, e.g.
function drawLines() {
var canvas = layer.getCanvas();
var context = canvas.getContext();
var scaleX = stage.getScaleX();
var scaleY = stage.getScaleY();
context.beginPath();
context.moveTo(targetX*scaleX,targetY*scaleY);
...
}
I changed the css on my canvas a little to include:
background-size: contain;
background-repeat: no-repeat;
So far, we have scaled the content to the size of the containing iframe. However, we also need to make that iframe have the right size.
So I added some javascript to the calling page:
<script>
function scaleIFrame() {
var target_width = 850;
var container_width = $("#iframe-parent").width();
var width = target_width;
if (container_width<target_width) {
width = container_width;
}
$("#iframe-parent iframe").css("width",width+"px");
}
window.onresize = function(event) {
scaleIFrame();
}
scaleIFrame();
</script>
This leaves me with just one problem: setting the height of the iframe. In theory I should be able to access the height of the contents of the iframe using something like this (see this link):
var iframe = $("iframe");
var iframe_internal = iframe.contents().find("#my-content");
iframe.css("height",iframe_internal.style.height+"px");
This requires the two sites involved to be at the same domain; if they are on the same top-level domain you can still do it if you include a document.domain tag in both the iframe content and the calling page (see this SO post). You may also want to give your localhost the domain name you are using, so that you can test it (see this SO post) - I just added a new line to my /etc/hosts file: '127.0.0.1 local.example.com'.
I followed this last process (my two sites have the same top-level domain), but when I print out the iframe_internal variable it is an object with zero length, so something is going wrong here.
Still, I am very happy to have got this far. It works on the iPad and all browsers I have tested.

Hiding the toolbars surrounding an embedded pdf?

Though I think the answer maybe in this other question's answer concerning the pdf specification, is it possible to not display the adobe acrobat toolbars in an embedded pdf document?
If you use any browser besides Firefox browser, then the following code will embed a PDF file without any toolbars:
<embed
src="http://URL_TO_PDF.com/pdf.pdf#toolbar=0&navpanes=0&scrollbar=0"
width="425" height="425" />
Please note that this does not work on Firefox
See the Web Designer's Guide blog post for details.
See the full list of embedded tag parameters for more information.
You can use #toolbar to hide above toolbar.. if toolbar =0, it will disable it.. when toolbar=1, this will enable it.. hope so it will work. this works for me
<embed src="filename.pdf#toolbar=0" width="500" height="375"> (Disable toolbar)
<embed src="path/filename.pdf#toolbar=1" width="500" height="375"> (Enable toolbar
There is no guarantee that using #toolbar=0 in the URL will work, as this is exclusive to browsers that use the Adobe viewer, it may be that other viewers even have similar parameters to maintain compatibility, but certainly not everyone follows that, such as browsers for MacOS browsers or Linux.
In most browsers it is possible to change the view, which also probably will not work with #toolbar=0, because the viewer is something apart from the browser, for example Firefox has its own viewer internally and that does not work with this #toolbar=0, see the result of:
<iframe
src="sample.pdf#toolbar=0"
width="900"
height="200"
></iframe>
<br>
<embed type="application/pdf"
src="sample.pdf#toolbar=0"
width="900"
height="200"
>
And even if it works in Firefox as well as Chrome with extensions, it is possible to change the PDF viewer to anything else that may not support this parameter.
Even if you can remove all the buttons you want, you can still copy your PDF, or images, because everything is downloaded to your computer before rendering, the user can simply press F12 to open DevTools (Chrome / Firefox), look the network tab and filter it to get all PDFs loaded on the current page and by DevTools it will copy the PDF to any folder of it.
There is no way to stop, it is only possible to hinder. As already seen neither "iframe" nor "embed" will solve, I suggest (it's just a suggestion) use PDF.js.
So you can create your own buttons, navigation and the like and everything will run in <canvas>, example:
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf';
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
var pdfDoc = null,
pageNum = 1,
pageRendering = false,
pageNumPending = null,
scale = 1.5,
canvas = document.getElementById('pdf-example'),
ctx = canvas.getContext('2d');
function renderPage(num) {
pageRendering = true;
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
pageRendering = false;
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('page_num').textContent = num;
}
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
/**
* show previous page
*/
function onPrevPage() {
if (pageNum > 1) {
pageNum--;
queueRenderPage(pageNum);
}
}
document.getElementById('prev').addEventListener('click', onPrevPage);
/**
* show next page
*/
function onNextPage() {
if (pageNum < pdfDoc.numPages) {
pageNum++;
queueRenderPage(pageNum);
}
}
document.getElementById('next').addEventListener('click', onNextPage);
/**
* PDF async "download".
*/
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
//Set loaded PDF to main pdfDoc variable
pdfDoc = pdfDoc_;
//Show number of pages in document
document.getElementById('page_count').textContent = pdfDoc.numPages;
renderPage(pageNum);
});
#pdf-example {
border: 1px solid black;
}
<script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>
<div>
<button id="prev">Previous page</button>
<button id="next">Next page</button>
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>
<canvas id="pdf-example"></canvas>
Note that I used 1.5 to scale:
scale = 1.5,
...
var viewport = page.getViewport({scale: scale});
You can change this as needed. I recommend that you adjust it according to the view-port measurement (you can use window.innerWidth to calculate), but also make a minimum measurement, so it will be adaptive to different resolutions.
This works for me for hiding the pdf print view in react application
<iframe src={`${resumeUrl}#toolbar=0`} width="100%" height={500} />