Update elements inside an externally loaded webview - javascript

Update
I found 'webview.executeScript' however, I can't access any of the custom functions.
This is a major step forward though. Any suggestions welcome.
Original post
We developed a Kiosk Web Extension for Chrome OS that loads an externally hosted webpage. The page is loaded into a webview. This page display dynamic information that gets updated daily. In order to push "manual" updates out to the page, we maintain an open WebSocket connection to the Kiosk app. This allows us to refresh the page, update the page, push information, etc. However, we need to access either the javascript loaded inside the webview or we need to access the elements. I'm not sure if I'm explaining this right, or if it is possible to do what I am asking.
Right now we are opening two connections to the websocket server. One is from the webpage and the other is from the extension. The goal is to cut down to one connection.
I added pseudo code to give an idea of what is I need to do.
Chrome Web Extension Kiosk index.html
<html>
<head>
<title></title>
</head>
<body>
<div id="page">
</div>
</body>
</html>
Kiosk example background js
(note: I know this wouldn't be doable via jquery)
document.onLoad({
$("#page").html('<webview id="browser" src="example.com"></webview>');
});
function ReceiveWebSocketMessage(msg) {
switch (msg.cmd) {
case "updatedate":
$("browser").UpdateDate(msg.data);
break;
case "reboot":
chrome.runtime.RebootDevice();
break;
}
}
Webpage example.com
<html>
<head>
<title></title>
</head>
<body>
<div id="datetime">
1/1/2016
</div>
</body>
</html>
Webpage example JS http://example.com/app.js
function UpdateDate(newdate) {
$("#datetime").html = newdate;
}
I threw together a quick diagram of what the old design is like and what the new design is.
To sum it up, I need to access functions that are on the external page. I've not had luck trying to accomplish it.

Resolved! I found the following examples:
https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/webview-samples/shared-script
Basically I added this to my code:
function Execute(code) {
var webview = document.querySelector('webview');
webview.executeScript({
code: generateScriptText(code)
});
}
function generateScriptText(fn) {
var fnText = fn.toString()
.replace(/"/g, '\\"') // Escape double-quotes.
.replace(/(\r?\n|\r)/g, '\\n'); // Insert newlines correctly.
var scriptText =
'(function() {\n' +
' var script = document.createElement("script");\n' +
' script.innerHTML = "(function() { (' + fnText + ')(); })()" \n' +
' document.body.appendChild(script);\n' +
'})()';
return scriptText;
}

Related

Can you use JavaScript inside an email, which is sent using Python? [duplicate]

This question already has answers here:
Is JavaScript supported in an email message?
(11 answers)
Closed 5 years ago.
Can you use JavaScript inside an email, which is sent using Python?
My aim is to send a working clock inside an email.
I am trying to use Python to do so. I am using IDLE and the Python libraries stmplib, email and html2text to send emails. My code looks like the code shown below. I omitted some details (style and script) as they are unimportant.
me = "my.email#gmail.com"
you = "my.email#gmail.com"
msg = MIMEMultipart('alternative')
msg['Subject'] = "Clock"
msg['From'] = me
msg['To'] = you
html = """\
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Clock</title>
<style></style>
</head>
<body>
<div class="clock">
<p class="clockhour">HH</p>
<p class="clocksym1">:</p>
<p class="clockminute">MM</p>
<p class="clocksym2">:</p>
<p class="clocksecond">SS</p>
</div>
<script type="text/javascript"></script>
</body>
</html>
"""
text = html2text(html)
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
msg.attach(part1)
msg.attach(part2)
s = SMTP('smtp.gmail.com:587')
s.ehlo()
s.starttls()
s.login("my.email#gmail.com", "my password")
s.sendmail(me, you, msg.as_string())
s.quit()
The full version of the HTML in this code gives me a properly functioning clock, but if I attempt sending it to myself using Gmail I receive a different result.
Viewing the HTML:
In Gmail:
This shows, that parts of the CSS load, but others like the font or the font size don't. It also shows that the JavaScript does not load. (Normally viewing the HTML code in a browser gives a functioning clock, while in an email doesn't.)
Is there a way to send an email with this clock?
Short Answer: No. You can't use JavaScript for email template.
Tricky way: You can work on relevant file and get the parsed value in your template file using server side language.
Example:
clock.js
// code for js
template.php
// echo the value
// The value is rendered in html and works in email template too.
But this case is not suitable for you as you're trying to implement countdown clock. This is suitable only for static value.
However, linking to external page content will help you to show the timer.
For your case, You may try using http://motionmailapp.com/
Hope, this helps!
javascript is unsupported in email html, but at least you can place a link to the page with clock countdown.

Refresh using Page.js gives 404 Not Found

I have just started using page.js, a routing library that I intend to use to make a single page application with handlebars. I will use the routes to call different handlebar templates. So far, this functionality is working and is as quick as I had hoped.
I am currently encountering an issue where refreshing the page (pressing F5) or copying the URL, and pasting it into a new tab gives me a 404 not found error. It is not calling the not found page that I created in my app.
The code below is a copy of: https://github.com/visionmedia/page.js/tree/master/examples/notfound
<!DOCTYPE html>
<html>
<head>
<title>Not Found</title>
<script src="/page.js"></script>
</head>
<body>
<h1>Not Found</h1>
<p></p>
<ul>
<li>/</li>
<li>/about</li>
<li>/contact</li>
<li>/not-found</li>
</ul>
<script>
page.base('/notfound');
page('/', index);
page('/about', about);
page('/contact', contact);
page('*', notfound);
page();
function index() {
document.querySelector('p')
.textContent = 'viewing index';
}
function about() {
document.querySelector('p')
.textContent = 'viewing about';
}
function contact() {
document.querySelector('p')
.textContent = 'viewing contact';
}
function notfound() {
document.querySelector('p')
.textContent = 'not found';
}
</script>
</body>
When I refresh this page, I am presented with my localhost's 404 page. I get the same result when I use the link http://127.0.0.1/notfound/about.
My question is this: does page.js support refreshing the browser, or using links to access specific portions of my application?
It seems that the question I should really be asking is this: Would it be possible for the web server to redirect all navigation to the page that loads the application? The answer is Yes.
It seems that refreshing the browser would be a common case. An acceptable solution to this would also be to catch any refresh attempts, and redirect them to the main page. Using links to access specific portions of my application is not as crucial, but would be a nice touch.

How to use google app script property service in a html applet

Good morning and thank you in advance for the help. I am a noobi at java/gas scripting so any help is appreciated.
On a google spreadsheet I have a custom menu that launches a small html menu that I would like to be able to launch various web pages from. The actual addresses are variable. I have set those as Keys with the property service when the page launches.
Here is the html code (taken from another example and trying to adapt)"
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script type="text/javascript">
var myArr = ["Peter", "Paul", "Tony", "Adam"];
function display(name) {
var accScriptPageLinkID= PropertiesService.getScriptProperties().getProperty('scriptPageLinkAdd');
Logger.log(accScriptPageLinkID)
alert(name);
}
for(var i = 0; i < 4; i ++) {
document.write('<input type="button" onclick="display(this)" name="'+ myArr[i] + '" value="'+ myArr[i] +'">'); // Will log Peter, Paul..
}
</script>
</body>
</html>
I need to modify the above code so that when the button Peter is pressed it opens the Script Page linked under the Property Service Key 'scriptPageLinkAdd'.
Or if there is an easier way to create a dynamic html page for my menu that is linked to cells in the google spreadsheet, please advise.
Mike
PropertiesService (and Logger too) are server-side AppsScript classes - they can't be invoked directly from the client side (your html page).
To invoke them on the server side from your html page you must use google.script.run.withSuccessHandler(clientSideFunctionToProcessReturnedData).someServerSideFunction() which can return some data back to your html page.
Learn more about HtmlService and communicating with the server here

How can I make a 'notification' sound play when a webpage is opened on an Android phone?

I've been searching today and have found some answers, such as this:
<head>
<title>Audio test</title>
<script type="text/javascript">
// #param filename The name of the file WITHOUT ending
function playSound(filename){
document.getElementById("sound").innerHTML='<audio autoplay="autoplay"><source src="' + filename + '.mp3" type="audio/mpeg" /><source src="' + filename + '.ogg" type="audio/ogg" /><embed hidden="true" autostart="true" loop="false" src="' + filename +'.mp3" /></audio>';
}
</script>
</head>
<body>
<button onclick="playSound('bing');">Play</button>
<div id="sound"></div>
</body>
For the answer above, I believe I just need to enter the correct file name (ex. mydomain.com/correctfilename.mp3) where 'filename' is in that script.
But I'm looking for something a little different and a little faster load-time wise. I'm wondering if I can have a 'default' Android notification sound played when the site is opened. I've found something similar to what I need right here:
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
But when I put that in the HTML file, it doesn't work, and I think it's because it's not javascript.
I know there are ways to access whatever your phone has that makes it vibrate, so I'm thinking there could be a way to access the pre-loaded sounds it has. Can I do this with a script?
I think you are asking if you can do something from the web page, not from a specific app on the device - for that way use WebView.
For any web page to access device services via the browser, there is the W3C Device API Working Group, which has produced a Vibration API, and even works already on Android Chrome Beta 39 and others like so:
navigator.vibrate(2000);
I'm not aware, however, of some way to play a default sound/vibration that follows the device environment like say, Windows API handles it.

Options to store data on desktop, using webpage

Goal:
To sum it up, I'm trying to replace an excel spreadsheet. I'm creating an application that will run in IE9, but does not connect to the internet or an intranet (I know, I know. Just bear with me. If you're curious read more below). It needs to use CRUD (create, read, update, and delete) methods on a set of data that changes daily. The dataset must persist even when the browser is closed.
Question:
What options are available, using javascript and html, for storing data on the local computer the web page is accessed on? I'm doing this at work, so there will be no server-side to this. I also will not be able to install any software on the computer, although I can download javascript plugins. The webpage will be loaded from a file on the computer, using Win 7 and IE9.
Background:
This deserves an explanation. I use an excel spreadsheet to track a set of data that changes daily. I'm learning HTML and javascript, and I can create a much better (and easier to use) solution as a webpage. I can create the UI / UX, but I'm having a difficult time figuring out how to store the data on the local computer. Any good suggestions?
Attempts:
Unfortunately, it seems localStorage is not an option. I'm attempting to use jStorage, but I've been running into problems there, also. A similar set of problems has been encountered using simpleStorage.
Thank you for considering, please let me know if any more info is needed, or if I need to clarify something.
Addendum:
Localstorage, and other forms of HTML5 storage, do not work. Officially it does, unofficially it is very buggy. See blog post here, and SO answer here. Either way, with the following simple code:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Backlog Tracker</title>
<script src="jquery-2.1.1.min.js"></script>
<script src="backlog_localstorage.js"></script>
</head>
<body>
</body>
</html>
and javascript (ref as "backlog_localstorage.js" above):
$(document).ready(function(){
$("body").append("<button>Try It</button>");
$("button").click(function(){
localStorage.setItem("key1", "Hello");
console.log(localStorage.getItem("key1"));
});
});
... I get the following error: "SCRIPT5007: Unable to get value of the property 'setItem': object is null or undefined" on the line localStorage.setItem("key1", "Hello");
HTA (which is really just an html file with one extra tag and a different file extension) is one possible solution for windows users:
Important: Save as demo.hta to run on windows as an app
<!DOCTYPE html>
<html> <!-- some parts lifted from
http://msdn.microsoft.com/en-us/library/ms536496(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms536473(v=vs.85).aspx
-->
<head>
<title>State Saving Demo</title>
<hta:application id="App"
application="yes"
applicationname="demo"
icon="calc.exe"
border="thin"
caption="yes"
sysmenu="yes"
showintaskbar="yes"
singleinstance="yes"
sysmenu="no"
maximizeButton="yes"
minimizeButton="yes"
navigable="no"
scroll="yes"
contextmenu="no"
selection="no"
windowstate="normal" >
<!-- Use Internet Explorer 10 Standards mode (to use JSON, CSS3, etc...) -->
<meta http-equiv="x-ua-compatible" content="IE=10">
</head>
<body onload=loadMe() >
<h1 id=h1>Command-line args: </h1>
<h3>Persisted Text</h3>
<textarea rows=20 cols=100 id=mydata onchange=saveMe() >
You can change me and i won't forget!
</textarea>
<script>
document.title+=" - Today is " + Date(); // task/title bar demo
h1.innerHTML+= JSON.stringify( App.commandLine ); // optional invocation info here (much like a real app)
// app-specific custom code:
FILENAME="state.txt";
function saveMe(){save(FILENAME, mydata.value); }
function loadMe(){mydata.value=load(FILENAME) || mydata.value;}
// generic utils:
function load(filename) { //IE FSO file Loader
var file,
text="",
fso= new ActiveXObject('Scripting.FileSystemObject');
try{
file = fso.OpenTextFile(filename, 1, false);
text = file.readAll();
file.Close();
}catch(y){}
return text;
}
function save(filename, sData){ //IE FSO file Saver
var file,
fso = new ActiveXObject('Scripting.FileSystemObject');
file = fso.CreateTextFile(filename, 2, false);
file.write(sData);
file.Close();
return file;
}
</script>
</body>
</html>
I recently re-discovered HTAs, and they are not half bad. I don't think I would want to distribute and maintain them, but HTA's are an easy way to make simple desktop app using HTML, CSS, and JS. Its nice not to have to build anything to "recompile" the app after changes are made. saves a few steps compared to node-webkit, packaged apps, air, cordova, etc, but HTA's have a major downside: they only work on windows afaik...
Looks to me like you can use LocalStorage, the big question is how are you trying to store it? You can easily store an object/array into LocalStorage, and that object/array can be your data, then JS can output this into a table. If you're looking to store actual files then you're looking at something more like an ActiveX plugin.
http://caniuse.com/#search=localstorage
Alternatively if you have internet access through a desktop or a phone you can put this on Google Drive. This would be far easier than reinventing the wheel.

Categories