Converting IFRAME contents to image - dart

I fetch a URL into an IFRAME, and now would like to capture a thumbnail of the result to later show the user the links they have followed.
void receiveHtml(Event e) {
...
iframe.convertToImage... // <----- ????? How to do this?
}
IFrameElement iframe = query('#iframehtml') as IFrameElement;
...
iframe.on.load.add(receiveHtml);
...
iframe.src = url; // E.g. url='http://someplace.com/dir/'
Is there a way in DART to capture the iframe document to an image? (which I can then shrink to a thumbnail and store for later).

You can't do this on the client-side, at least not without the iframe being in the same origin ("the same website"). Otherwise, it would be a security risk, because it opens the door to many possibilities like screenshotting a bank website with the user's bank account details.
However, you could do this on the server side, but it does not get much easier.
One thing you could do is to install webkit2png and let it make screenshots of websites. You could just call it something like this:
import 'dart:io';
main() {
Process.run('python', ['/path/to/webkit2png', 'http://google.com']).then((result) {
// Here you can open and do whatever you want with the screenshots.
// The files are placed in the current directory.
print(new File('somescreenshot.png').readAsBytesSync());
});
}

Related

HTMLIFrameElement.contentWindow.print() from GoogleSheets is not opening print preview

I am using GoogleSheets to print a png/image file using HTMLService. I created a temporary Iframe element with an img tag in the modalDialog and call IFrame element's contentWindow.print() function after IFrame element and its image are loaded. (I have not set visibility:hidden attribute of IFrame element to check if image is getting loaded.)
However, I only see the printer dialog without any print preview. I am testing on Firefox. Am I missing anything?
[Updated] - I am using Googles Apps script. performPrint() is in printJsSource.html and openUrl() is in Code.gs.
Inside printJsSource.html
function performPrint(iframeElement, params) {
try {
iframeElement.focus()
// If Edge or IE, try catch with execCommand
if (Browser.isEdge() || Browser.isIE()) {
try {
iframeElement.contentWindow.document.execCommand('print', false, null)
} catch (e) {
iframeElement.contentWindow.print()
}
} else {
// Other browsers
iframeElement.contentWindow.print() // as I am using Firefox, it is coming here
}
} catch (error) {
params.onError(error)
} finally {
//cleanUp(params)
}
}
Inside Code.gs
function openUrl() {
var html = HtmlService.createHtmlOutputFromFile("printJsSource");
html.setWidth(500).setHeight(500);
var ui = SpreadsheetApp.getUi().showModalDialog(html, "Opening ..." );
}
I think there is some general confusion about the concept
First of all, function performPrint() seems to be a client-side Javascript funciton, while function openUrl() is a server-side Apps Script function.
While you did not specify either you use Google Apps Script - if you do so, function openUrl()belongs into the code.gs file and function performPrint() into printJsSource.html file
function openUrl() allows you to open a modal dialog which can show some data on the UI, e.g. your image
Do not confuse this behavior with actual printing (preview)!
It is NOT possible to trigger the opening of a Google Sheets printing preview programamticaly!
The Javascript method you are using iframeElement.contentWindow.print() might trigger the printing of the whole content of a browser window (different from the Google Sheets printing dialog, also depends on the browser), but if you try to incorporate it into the client-side coe of an Apps Script project, you will most likely run into restrictions due to the scopes of modal diloags and usage of iframes.
While from your code it is hard to say either you implemented the funcitons in the correct files of the Apps Script project, keep in mind that to work with iframes you need to specify in function openUrl()
html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

Embed analytics code within image to be triggered when image is displayed

Is it possible to pack analytics code within an image and have that code fire when the image is loaded on a webpage?
The image would be inserted onto a page through a file upload form field such as if I were to add an image to this question where I have no direct access to add HTML or JS to the page.
Goal being to track page views on pages which I have no access to any code, only the ability to upload an image.
Almost kind of like a 'Trojan horse' approach but without any malicious intent.
Tracking pixels requires specific structure and specific server.
So I cannot imagine anything like Trojan horse, but you can track image load as an event.
Try something like this:
Single purpose client side
<img src="" alt="Facebook is new god" id="fblogo"/>
<script type="text/javascript">
window.onload = function () {
var logo = document.getElementById('fblogo');
logo.onload = function () {
ga('send', 'event', 'FB', 'Loaded');
};
logo.src = 'https://facebook.com/fb/logo.png';
};
</script>
Measurement protocol way - server side
https://www.google-analytics.com/collect
?v=1 // Protokol version
&tid=UA-XXXX-Y // Property ID
&cid=55568765456 // Client ID stored in database or random number
&dh=forum.eu // referrer
&dp=image78974.png // filename
&t=event // send instruction
&ni=1 // non inteaction flag
&ec=Image // Event Category
&ea=Load // Event Action
&el=image78974.png // Event Label

ms-webview src property points to "local-stream:///" not "ms-appdata:///"

I have some code that loads an html file in a ms-webview within a Windows 8 store app (winJS) and I'm having an issue checking the URL src of the ms-webview. Basically, the user is able to navigate within the local html files, but I want to detect when they are back on the "home" screen...
var home = "ms-appdata://local/somefile.html";
myWebView.addEventListener("MSWebViewContentLoading", function(e) {
console.log(myWebView.src); // something like: ms-local-stream://[app_key]/somefile.html
console.log(e.uri); // same as above
if (myWebView.src === home) {
// nope...
}
});
myWebView.navigate(home);
As you can see above, the webview doesn't seem to give me a way to get the URL that I actually navigated to... Thoughts?
And yes, I could inspect the ms-local-stream URL path for the file I'm looking for, but surely there's a way to get the URL that was navigate to from the webview??

Photoswipe Custom Hashtag Immediately Closes Slideshow

Testing on the desktop with JQM doesn't produce this issue, so it's difficult to pinpoint.
Backstory: I have created server side code (php) to accept a query string and open a gallery straight to a picture. But if a user wants to share a link while surfing a gallery on a mobile device, and in particular a certain photo; most Mobile Browsers share the core link and not the actual photo. It's easy in the events when swiping to create a URL hashtag modifier for the URL with the photo id ( For example #photoID=987), but only if the gallery is originally started with no hashtags. It's then easy to share with a Phone's Native methods.
(function(window, $, PhotoSwipe){
$(document).ready(function(){
//More Code is here but not needed fro this question
$(photoSwipeInstance).bind(PhotoSwipe.EventTypes.onDisplayImage, function(e){
var pid = codeThatGetsPhotoIDFromDisplayedIMGURL();
window.location.hash = '&pid='+pid[0];
});
if(getUrlVars()["pid"]!=null || getUrlVars()["pid"]!=undefined)
{
console.log(getUrlVars()["pid"]);
var photopid= getPhoto(getUrlVars()["pid"]);
photoSwipeInstance.show(photopid);
}
});//End Documentstrong text
}(window, window.jQuery, window.Code.PhotoSwipe));
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
Issue: If a gallery is loaded with a hashtag the gallery will pop up the proper image but then immediately closes the slide show. And every photo past this point performs in the same manner, slideshow opens then closes.
I have turned off all AJAX, and hashtag anchor functions JQM utilizes. This hashtag url functions works as intended when using a Desktop browser but not when using any Mobile browser.
Has someone else tried this functionality?
I probably made this much more confusing then it is in my description.
Answer: JQM's hashtag handlers did not need to be turned off instead. Photoswipe needed this handler added to the options: backButtonHideEnabled: false
JQM's hashtag handlers did not need to be turned off instead. Photoswipe needed this handler added to the options: backButtonHideEnabled: false

Editing a BrowserField's History

I have a BrowserField in my app, which works great. It intercept NavigationRequests to links on my website which go to external sites, and brings up a new windows to display those in the regular Browser, which also works great.
The problem I have is that if a user clicks a link to say "www.google.com", my app opens that up in a new browser, but also logs it into the BrowserHistory. So if they click back, away from google, they arrive back at my app, but then if they hit back again, the BrowserHistory would land them on the same page they were on (Because going back from Google doesn't move back in the history) I've tried to find a way to edit the BrowserField's BrowserHistory, but this doesn't seem possible. Short of creating my own class for logging the browsing history, is there anything I can do?
If I didn't do a good job explaining the problem, don't hesitate for clarification.
Thanks
One possible solution to this problem would be to keep track of the last inner URL visited before the current NavigationRequest URL. You could then check to see whether the link clicked is an outside link, as you already do, and if it is call this method:
updateHistory(String url, boolean isRedirect)
with the last URL before the outside link. Using your example this should overwrite "www.google.com" with the last inner URL before the outside link was clicked.
Here is some half pseudocode/half Java to illustrate my solution:
BrowserFieldHistory history = browserField.getHistory():
String lastInnerURL = "";
if navigationRequest is an outside link {
history.updateHistory(lastInnerURL, true);
// Handle loading of outer website
} else {
lastInnerURL = navigationRequest;
// Visit inner navigation request as normal
}
http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/browser/field2/BrowserFieldHistory.html#updateHistory(java.lang.String, boolean)
I had a similar but a little bit different issue. Special links in html content like device:smth are used to open barcode scanner, logout etc and I wanted them not to be saved in BrowserFieldHistory. I found in WebWork source code interesting workaround for that. All that you need is throw exception at the end like below:
public void handleNavigationRequest( BrowserFieldRequest request ) throws Exception {
if scheme equals to device {
// perform logout, open barcode scanner, etc
throw new Exception(); // this exception prevent saving history
} else {
// standard behavior
}
}

Resources