How to read/intercept JavaScript on the page before it is executed? - firefox-addon

I would like to intercept location.reload(); via a Firefox API or by reading the JS on the page (remote & embedded) before it is loaded/executed or by any other means possible.
Example:
<head>
<script>
window.setTimeout(function() { location.reload(); }, 10000);
</script>
</head>
I have tried beforescriptexecute event listener (via GreaseMonkey & // #run-at document-start) but it is fired AFTER above is executed.
Update:
beforescriptexecute works nicely on REMOTE scripts since the event beforescriptexecute is fired before making the request (but then on the script src and not script content). It is different if the script is within normal script tag (and not remote), as per the example given. The beforescriptexecute fires and the script content can be rewritten but by then the window.setTimeout() has already fired and it is executing.

The beforescriptexecute should work. Its a non-greasemonkey event:
https://developer.mozilla.org/en-US/docs/Web/Events/beforescriptexecute
You can do stuff like this:
document.addEventListener("beforescriptexecute", function(e) {
src = e.target.src;
content = e.target.text;
if (src.search("i18n.js") > -1) {
// Stop original script
e.preventDefault();
e.stopPropagation();
window.jQuery(e.target).remove();
var script = document.createElement('script');
script.textContent = 'script you want';
(document.head || document.documentElement).appendChild(script);
script.onload = function() {
this.parentNode.removeChild(this);
}
}

Related

How to automatically change agent status on Amazon Connect?

I need step by step directions on how to load the CCP into a webpage and use the streams API. I would need the javascript to turn the agent from "missed" to "available" after 25 seconds.
Currently we have to manually update staus which doesn't make sense for our use case.
I saw on the Amazon Connect forum someone made mention of a way to automatically change the status of from Missed to Available.
If you're embedding the CCP and using the Streams API, you can check
the agent status on refresh, and if it's in Missed Call, set it to
Available. I have this set to happen after 10 seconds.
For an embedded CCP you can do this using Stream API. You can subscribe to the agent refresh status, and do it there.
connect.agent(function (agent) {
logInfoMsg("Subscribing to events for agent " + agent.getName());
logInfoMsg("Agent is currently in status of " + agent.getStatus().name);
agent.onRefresh(handleAgentRefresh);
}
function handleAgentRefresh(agent) {
var status = agent.getStatus().name;
logInfoEvent("[agent.onRefresh] Agent data refreshed. Agent status is " + status);
//if status == Missed Call,
// set it to Available after 25 seconds."
//For example -but maybe this is not the best approach
if (status == "Missed") { //PLEASE review if "Missed" and "Availble" are proper codes
setTimeout(function () {
agent.setState("Available", {
success: function () {
logInfoEvent(" Agent is now Available");
},
failure: function (err) {
logInfoEvent("Couldn't change Agent status to Available. Maybe already in another call?");
}
});
;
}, 25000);
}
}
If you also need to know how to embed the CCP in a website, you can just do something like this
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
<script type="text/javascript" src="amazon-connect-1.4.js"></script>
</head>
<!-- Add the call to init() as an onload so it will only run once the page is loaded -->
<body onload="init()">
<div id=containerDiv style="width: 400px;height: 800px;"></div>
<script type="text/javascript">
var instanceURL = "https://my-instance-domain.awsapps.com/connect/ccp-v2/";
// initialise the streams api
function init() {
// initialize the ccp
connect.core.initCCP(containerDiv, {
ccpUrl: instanceURL, // REQUIRED
loginPopup: true, // optional, defaults to `true`
region: "eu-central-1", // REQUIRED for `CHAT`, optional otherwise
softphone: { // optional
allowFramedSoftphone: true, // optional
disableRingtone: false, // optional
ringtoneUrl: "./ringtone.mp3" // optional
}
});
}
</script>
</body>
</html>
You can see the documentation for StreamsAPI here https://github.com/amazon-connect/amazon-connect-streams/blob/master/Documentation.md

hide browser back button after user gets logout [duplicate]

I am doing an online quiz application in PHP. I want to restrict the user from going back in an exam.
I have tried the following script, but it stops my timer.
What should I do?
The timer is stored in file cdtimer.js.
<script type="text/javascript">
window.history.forward();
function noBack()
{
window.history.forward();
}
</script>
<body onLoad="noBack();" onpageshow="if (event.persisted) noBack();" onUnload="">
I have the exam timer which takes a duration for the exam from a MySQL value. The timer starts accordingly, but it stops when I put the code in for disabling the back button. What is my problem?
There are numerous reasons why disabling the back button will not really work. Your best bet is to warn the user:
window.onbeforeunload = function() { return "Your work will be lost."; };
This page does list a number of ways you could try to disable the back button, but none are guaranteed:
http://www.irt.org/script/311.htm
It is generally a bad idea overriding the default behavior of the web browser. A client-side script does not have the sufficient privilege to do this for security reasons.
There are a few similar questions asked as well,
How can I prevent the backspace key from navigating back?
How can I prevent the browser's default history back action for the backspace button with JavaScript?
You can-not actually disable the browser back button. However, you can do magic using your logic to prevent the user from navigating back which will create an impression like it is disabled. Here is how - check out the following snippet.
(function (global) {
if(typeof (global) === "undefined") {
throw new Error("window is undefined");
}
var _hash = "!";
var noBackPlease = function () {
global.location.href += "#";
// Making sure we have the fruit available for juice (^__^)
global.setTimeout(function () {
global.location.href += "!";
}, 50);
};
global.onhashchange = function () {
if (global.location.hash !== _hash) {
global.location.hash = _hash;
}
};
global.onload = function () {
noBackPlease();
// Disables backspace on page except on input fields and textarea..
document.body.onkeydown = function (e) {
var elm = e.target.nodeName.toLowerCase();
if (e.which === 8 && (elm !== 'input' && elm !== 'textarea')) {
e.preventDefault();
}
// Stopping the event bubbling up the DOM tree...
e.stopPropagation();
};
}
})(window);
This is in pure JavaScript, so it would work in most of the browsers. It would also disable the backspace key, but that key will work normally inside input fields and textarea.
Recommended Setup:
Place this snippet in a separate script and include it on a page where you want this behavior. In the current setup it will execute the onload event of the DOM which is the ideal entry point for this code.
Working DEMO!
It was tested and verified in the following browsers,
Chrome.
Firefox.
Internet Explorer (8-11) and Edge.
Safari.
I came across this, needing a solution which worked correctly and "nicely" on a variety of browsers, including Mobile Safari (iOS 9 at time of posting). None of the solutions were quite right. I offer the following (tested on Internet Explorer 11, Firefox, Chrome, and Safari):
history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event)
{
history.pushState(null, document.title, location.href);
});
Note the following:
history.forward() (my old solution) does not work on Mobile Safari --- it seems to do nothing (i.e., the user can still go back). history.pushState() does work on all of them.
the third argument to history.pushState() is a url. Solutions which pass a string like 'no-back-button' or 'pagename' seem to work OK, until you then try a Refresh/Reload on the page, at which point a "Page not found" error is generated when the browser tries to locate a page with that as its URL. (The browser is also likely to include that string in the address bar when on the page, which is ugly.) location.href should be used for the URL.
the second argument to history.pushState() is a title. Looking around the web most places say it is "not used", and all the solutions here pass null for that. However, in Mobile Safari at least, that puts the page's URL into the history dropdown the user can access. But when it adds an entry for a page visit normally, it puts in its title, which is preferable. So passing document.title for that results in the same behaviour.
<script>
window.location.hash = "no-back-button";
// Again because Google Chrome doesn't insert
// the first hash into the history
window.location.hash = "Again-No-back-button";
window.onhashchange = function(){
window.location.hash = "no-back-button";
}
</script>
For restricting the browser back event:
window.history.pushState(null, "", window.location.href);
window.onpopstate = function () {
window.history.pushState(null, "", window.location.href);
};
This code will disable the back button for modern browsers which support the HTML5 History API. Under normal circumstances, pushing the back button goes back one step, to the previous page. If you use history.pushState(), you start adding extra sub-steps to the current page. The way it works is, if you were to use history.pushState() three times, then start pushing the back button, the first three times it would navigate back in these sub-steps, and then the fourth time it would go back to the previous page.
If you combine this behaviour with an event listener on the popstate event, you can essentially set up an infinite loop of sub-states. So, you load the page, push a sub-state, then hit the back button, which pops a sub-state and also pushes another one, so if you push the back button again it will never run out of sub-states to push. If you feel that it's necessary to disable the back button, this will get you there.
history.pushState(null, null, 'no-back-button');
window.addEventListener('popstate', function(event) {
history.pushState(null, null, 'no-back-button');
});
How to block coming backwards functionality:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
None of the most-upvoted answers worked for me in Chrome 79. It looks like Chrome changed its behavior with respect to the Back button after version 75. See here:
https://support.google.com/chrome/thread/8721521?hl=en
However, in that Google thread, the answer provided by Azrulmukmin Azmi at the very end did work. This is his solution.
<script>
history.pushState(null, document.title, location.href);
history.back();
history.forward();
window.onpopstate = function () {
history.go(1);
};
</script>
The problem with Chrome is that it doesn't trigger onpopstate event
unless you make browser action ( i.e. call history.back). That's why
I've added those to script.
I don't entirely understand what he wrote, but apparently an additional history.back() / history.forward() is now required for blocking Back in Chrome 75+.
React
For modal component in React project, the open or close of the modal, controlling browser back is a necessary action.
The stopBrowserBack: the stop of the browser back button functionality, also get a callback function. This callback function is what you want to do:
const stopBrowserBack = callback => {
window.history.pushState(null, "", window.location.href);
window.onpopstate = () => {
window.history.pushState(null, "", window.location.href);
callback();
};
};
The startBrowserBack: the revival of the browser back button functionality:
const startBrowserBack = () => {
window.onpopstate = undefined;
window.history.back();
};
The usage in your project:
handleOpenModal = () =>
this.setState(
{ modalOpen: true },
() => stopBrowserBack(this.handleCloseModal)
);
handleCloseModal = () =>
this.setState(
{ modalOpen: false },
startBrowserBack
);
This is the way I could it accomplish it.
Weirdly, changing window.location didn't work out fine in Google Chrome and Safari.
It happens that location.hash doesn't create an entry in the history for Chrome and Safari. So you will have to use the pushstate.
This is working for me in all browsers.
history.pushState({ page: 1 }, "title 1", "#nbb");
window.onhashchange = function (event) {
window.location.hash = "nbb";
};
history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
history.pushState(null, null, document.URL);
});
This JavaScript code does not allow any user to go back (works in Chrome, Firefox, Internet Explorer, and Edge).
This article on jordanhollinger.com is the best option I feel. Similar to Razor's answer but a bit clearer. Code below; full credits to Jordan Hollinger:
Page before:
<a href="/page-of-no-return.htm#no-back>You can't go back from the next page</a>
Page of no return's JavaScript:
// It works without the History API, but will clutter up the history
var history_api = typeof history.pushState !== 'undefined'
// The previous page asks that it not be returned to
if ( location.hash == '#no-back' ) {
// Push "#no-back" onto the history, making it the most recent "page"
if ( history_api ) history.pushState(null, '', '#stay')
else location.hash = '#stay'
// When the back button is pressed, it will harmlessly change the url
// hash from "#stay" to "#no-back", which triggers this function
window.onhashchange = function() {
// User tried to go back; warn user, rinse and repeat
if ( location.hash == '#no-back' ) {
alert("You shall not pass!")
if ( history_api ) history.pushState(null, '', '#stay')
else location.hash = '#stay'
}
}
}
<html>
<head>
<title>Disable Back Button in Browser - Online Demo</title>
<style type="text/css">
body, input {
font-family: Calibri, Arial;
}
</style>
<script type="text/javascript">
window.history.forward();
function noBack() {
window.history.forward();
}
</script>
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">
<H2>Demo</H2>
<p>This page contains the code to avoid Back button.</p>
<p>Click here to Goto NoBack Page</p>
</body>
</html>
This code was tested with the latest Chrome and Firefox browsers.
<script type="text/javascript">
history.pushState(null, null, location.href);
history.back();
history.forward();
window.onpopstate = function () { history.go(1); };
</script>
Try it with ease:
history.pushState(null, null, document.title);
window.addEventListener('popstate', function () {
history.pushState(null, null, document.title);
});
You can just put a small script and then check. It won't allow you to visit previous page.
This is done in JavaScript.
<script type="text/javascript">
function preventbackbutton() { window.history.forward(); }
setTimeout("preventbackbutton()", 0);
window.onunload = function () { null };
</script>
The window.onunload function fires when you try to visit back or previous page through browser.
Very simple and clean function to break the back arrow without interfering with the page afterward.
Benefits:
Loads instantaneously and restores original hash, so the user isn't distracted by URL visibly changing.
The user can still exit by pressing back 10 times (that's a good thing), but not accidentally
No user interference like other solutions using onbeforeunload
It only runs once and doesn't interfere with further hash manipulations in case you use that to track state
Restores original hash, so almost invisible.
Uses setInterval, so it doesn't break slow browsers and always works.
Pure JavaScript, does not require HTML5 history, works everywhere.
Unobtrusive, simple, and plays well with other code.
Does not use unbeforeunload which interrupts user with modal dialog.
It just works without fuss.
Note: some of the other solutions use onbeforeunload. Please do not use onbeforeunload for this purpose, which pops up a dialog whenever users try to close the window, hit backarrow, etc. Modals like onbeforeunload are usually only appropriate in rare circumstances, such as when they've actually made changes on screen and haven't saved them, not for this purpose.
How It Works
Executes on page load
Saves your original hash (if one is in the URL).
Sequentially appends #/noop/{1..10} to the hash
Restores the original hash
That's it. No further messing around, no background event monitoring, nothing else.
Use It In One Second
To deploy, just add this anywhere on your page or in your JavaScript code:
<script>
/* Break back button */
window.onload = function(){
var i = 0;
var previous_hash = window.location.hash;
var x = setInterval(function(){
i++;
window.location.hash = "/noop/" + i;
if (i==10){
clearInterval(x);
window.location.hash = previous_hash;
}
}, 10);
}
</script>
In a modern browser this seems to work:
// https://developer.mozilla.org/en-US/docs/Web/API/History_API
let popHandler = () => {
if (confirm('Go back?')) {
window.history.back()
} else {
window.history.forward()
setTimeout(() => {
window.addEventListener('popstate', popHandler, {once: true})
}, 50) // delay needed since the above is an async operation for some reason
}
}
window.addEventListener('popstate', popHandler, {once: true})
window.history.pushState(null,null,null)
I had this problem with React (class component).
And I solved it easily:
componentDidMount() {
window.addEventListener("popstate", e => {
this.props.history.goForward();
}
}
I've used HashRouter from react-router-dom.
You simply cannot and should not do this. However, this might be helpful:
<script type = "text/javascript" >
history.pushState(null, null, 'pagename');
window.addEventListener('popstate', function(event) {
history.pushState(null, null, 'pagename');
});
</script>
This works in my Google Chrome and Firefox.
This seems to have worked for us in disabling the back button on the browser, as well as the backspace button taking you back.
history.pushState(null, null, $(location).attr('href'));
window.addEventListener('popstate', function () {
history.pushState(null, null, $(location).attr('href'));
});
Just run code snippet right away and try going back
history.pushState(null, null, window.location.href);
history.back();
window.onpopstate = () => history.forward();
<script src="~/main.js" type="text/javascript"></script>
<script type="text/javascript">
window.history.forward();
function noBack() {
window.history.forward();
}
</script>
Try this to prevent the backspace button in Internet Explorer which by default acts as "Back":
<script language="JavaScript">
$(document).ready(function() {
$(document).unbind('keydown').bind('keydown', function (event) {
var doPrevent = false;
if (event.keyCode === 8 ) {
var d = event.srcElement || event.target;
if ((d.tagName.toUpperCase() === 'INPUT' &&
(
d.type.toUpperCase() === 'TEXT' ||
d.type.toUpperCase() === 'PASSWORD' ||
d.type.toUpperCase() === 'FILE' ||
d.type.toUpperCase() === 'EMAIL' ||
d.type.toUpperCase() === 'SEARCH' ||
d.type.toUpperCase() === 'DATE' )
) ||
d.tagName.toUpperCase() === 'TEXTAREA') {
doPrevent = d.readOnly || d.disabled;
}
else {
doPrevent = true;
}
}
if (doPrevent) {
event.preventDefault();
}
try {
document.addEventListener('keydown', function (e) {
if ((e.keyCode === 13)) {
//alert('Enter keydown');
e.stopPropagation();
e.preventDefault();
}
}, true);
}
catch (err) {
}
});
});
</script>
It's basically assigning the window's "onbeforeunload" event along with the ongoing document 'mouseenter' / 'mouseleave' events so the alert only triggers when clicks are outside the document scope (which then could be either the back or forward button of the browser)
$(document).on('mouseenter', function(e) {
window.onbeforeunload = null;
}
);
$(document).on('mouseleave', function(e) {
window.onbeforeunload = function() { return "You work will be lost."; };
}
);
Just set location.hash="Something". On pressing the back button, the hash will get removed from the URL, but the page won't go back.
This method is good for preventing going back accidentally, but for security purposes you should design your backend for preventing reanswering.
Some of the solutions here will not prevent a back event from occurring - they let a back event happen (and data held about the page in the browsers memory is lost) and then they play a forward event to try and hide the fact that a back event just happened. Which is unsuccessful if the page held transient state.
I wrote this solution for React (when react router is not being used), which is based on vrfvr's answer.
It will truly stop the back button from doing anything unless the user confirms a popup:
const onHashChange = useCallback(() => {
const confirm = window.confirm(
'Warning - going back will cause you to loose unsaved data. Really go back?',
);
window.removeEventListener('hashchange', onHashChange);
if (confirm) {
setTimeout(() => {
window.history.go(-1);
}, 1);
} else {
window.location.hash = 'no-back';
setTimeout(() => {
window.addEventListener('hashchange', onHashChange);
}, 1);
}
}, []);
useEffect(() => {
window.location.hash = 'no-back';
setTimeout(() => {
window.addEventListener('hashchange', onHashChange);
}, 1);
return () => {
window.removeEventListener('hashchange', onHashChange);
};
}, []);
I create one HTML page (index.html). I also create a one (mechanism.js) inside a script folder / directory. Then, I lay all my content inside of (index.html) using form, table, span, and div tags as needed. Now, here's the trick that will make back / forward do nothing!
First, the fact that you have only one page! Second, the use of JavaScript with span / div tags to hide and display content on the same page when needed via regular links!
Inside 'index.html':
<td width="89px" align="right" valign="top" style="letter-spacing:1px;">
<small>
<b>
IN
</b>
</small>
[ <span id="inCountSPN">0</span> ]
</td>
Inside 'mechanism.js':
function DisplayInTrafficTable()
{
var itmsCNT = 0;
var dsplyIn = "";
for (i=0; i<inTraffic.length; i++)
{
dsplyIn += "<tr><td width='11'></td><td align='right'>" + (++itmsCNT) + "</td><td width='11'></td><td><b>" + inTraffic[i] + "</b></td><td width='11'></td><td>" + entryTimeArray[i] + "</td><td width='11'></td><td>" + entryDateArray[i] + "</td><td width='11'></td></tr>";
}
document.getElementById('inOutSPN').innerHTML =
"" +
"<table border='0' style='background:#fff;'><tr><th colspan='21' style='background:#feb;padding:11px;'><h3 style='margin-bottom:-1px;'>INCOMING TRAFFIC REPORT</h3>" +
DateStamp() +
" - <small><a href='#' style='letter-spacing:1px;' onclick='OpenPrintableIn();'>PRINT</a></small></th></tr><tr style='background:#eee;'><td></td><td><b>###</b></td><td></td><td><b>ID #</b></td><td></td><td width='79'><b>TYPE</b></td><td></td><td><b>FIRST</b></td><td></td><td><b>LAST</b></td><td></td><td><b>PLATE #</b></td><td></td><td><b>COMPANY</b></td><td></td><td><b>TIME</b></td><td></td><td><b>DATE</b></td><td></td><td><b>IN / OUT</b></td><td></td></tr>" +
dsplyIn.toUpperCase() +
"</table>" +
"";
return document.getElementById('inOutSPN').innerHTML;
}
It looks hairy, but note the function names and calls, embedded HTML, and the span tag id calls. This was to show how you can inject different HTML into same span tag on same page! How can Back/Forward affect this design? It cannot, because you are hiding objects and replacing others all on the same page!
How can we hide and display? Here goes:
Inside functions in ' mechanism.js ' as needed, use:
document.getElementById('textOverPic').style.display = "none"; //hide
document.getElementById('textOverPic').style.display = ""; //display
Inside ' index.html ' call functions through links:
<img src="images/someimage.jpg" alt="" />
<span class="textOverPic" id="textOverPic"></span>
and
Introduction
In my case this was a shopping order. So I disabled the button. When the user clicked back, the button was disabled still. When they clicked back one more time, and then clicked a page button to go forward. I knew their order was submitted and skipped to another page.
In the case when the page actually refreshed which would make the button (theoretically), available; I was then able to react in the page load that the order was already submitted and redirected then too.
This code is full javascript.
Put this on your home page or whatever you need when someon goes back it brings them to the page they were previously on.
<script type="text/javascript">
function preventBack() {
window.history.forward();
}
setTimeout("preventBack()", 0);
window.onunload = function () { null };
</script>

Alert when code is running background in google sheet

Working with Google App script and Javascript, I managed to retrieve xls Gmail attachments, convert it to google sheets, send an warning email to some recipients, insert an event with the Google Drive folder link when a new attachment is added to it, and at the end I managed with a standalone script to import some of the data coming from such xls file converted to a main Google Sheet where one operator is working h24 ( updating some data to be forwarded later on and during the service itself).
The standalone script run every 30 minutes to check incoming mail ( the schedule for the next day or days), and when it find it, it execute the code.
The lock service is not available on standalone scripts up to now, so I cannot lock the document, so I wish to display a message to the user that the script is about to run and not edit anything, since other scripts bounded to the Spreadsheet are using the Lock service, and so the result could be quite disappointing. I searched info regarding this "alert", but I cannot find a clue about it.
Could you address me somewhere?
I could add a menu function instead of a standalone script, and the operator could select "Import data" and that's it, but I wish to automate the operation in background.
You could use the HTML Service. I don't know much about it myself but I think the following may do what you need:
At the top of you .gs file:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var htmlApp = HtmlService.createTemplateFromFile("html");
var status = "Loading....."
htmlApp.data = status;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
At the end (just before the last brace):
var status = "Finished!"
htmlApp.data = status;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
In a new HTML script file named 'html':
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Updating..</h2>
<p id="status">(innerHTML).</p>
<div id="imageico"></div>
<script>
var imageContainer = document.getElementById("imageico");
if (<?= data ?> != "Finished!"){
document.getElementById("status").innerHTML = "Running script, please wait..";
} else {
document.getElementById("status").innerHTML = "Finished! You can now close the window.";
closeBtn();
}
function closeBtn(){
var button = document.createElement("INPUT");
button.setAttribute("type", "button");
button.setAttribute("value", "Close");
button.setAttribute("onclick", "closeWindow();");
imageContainer.appendChild(button);
}
function closeWindow(){
google.script.host.close();
}
</script>
</body>
</html>
EDITED Based on comments
In your .gs file:
function test() {
htmlApp("","");
/*
*
* Put your code in here....
*
*/
Utilities.sleep(3000); // change this value to show the "Running script, please wait.." HTML window for longer time.
htmlApp("Finished!","");
Utilities.sleep(3000); // change this value to show the "Finished! This window will close automatically. HTML window for longer time.
htmlApp("","close"); // Automatically closes the HTML window.
}
function htmlApp (status,close) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var htmlApp = HtmlService.createTemplateFromFile("html");
htmlApp.data = status;
htmlApp.close = close;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
}
In the HTML script file named 'html':
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Updating..</h2>
<p id="status">(innerHTML).</p>
<div id="imageico"></div>
<script>
var imageContainer = document.getElementById("imageico");
if (<?= data ?> != "Finished!"){
document.getElementById("status").innerHTML = "Running script, please wait..";
} else {
document.getElementById("status").innerHTML = "Finished! This window will close automatically.";
}
if (<?= close ?> == "close"){
google.script.host.close();
}
</script>
</body>
</html>
Have a look at this Sample Spreadsheet.
I don't see any methods or sample scripts regarding your concern. But this documentation about alert might help. It will open a dialog box in the user's editor with the given message and an "OK" button. However, this method suspends the server-side script while the dialog is open and the script will resume after the user dismisses the dialog.
You may also execute alert dialogs before running your script.
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show alert', 'showAlert')
.addToUi();
}
function showAlert() {
var ui = SpreadsheetApp.getUi(); // Same variations.
var result = ui.alert(
'Please confirm',
'Are you sure you want to continue?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
ui.alert('Confirmation received.');
} else {
// User clicked "No" or X in the title bar.
ui.alert('Permission denied.');
}
}

Absolute paths to Trigger.io assets?

We're building a Trigger app with Chaplin underneath. It would be nice, for development purposes, if we could use absolute paths to our assets, a la:
<link rel="stylesheet" href="/_forge/stylesheets/app.css">
<script src="/_forge/javascripts/vendor.js"></script>
<script src="/_forge/javascripts/app.js"></script>
Is it possible to do this in Trigger?
Unfortunately different platforms have different URLs on Trigger (due to them having their own features and limitations).
If you want to get absolute paths you can use the file module and do something along the lines of:
forge.file.getLocal("js/app.js", function (file) {
forge.file.URL(file, function (url) {
$('body').append('<script src="'+url+'"></script>');
});
});
I'm not sure why an absolute path is useful though, I would recommend only using one html page (index.html) as navigating to a new page is slower on the phone than changing the dom using javascript. In which case all of your relative paths should always be the same.
The easiest thing might be to detect the whether or not forge is present in your index.html and load the javascript accordingly:
<script type="text/javascript">
function addScript(src, callback) {
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = src;
tag.onload = callback;
document.getElementsByTagName('head')[0].appendChild(tag);
}
var vendor = "javascripts/vendor.js";
var app = "javascripts/app.js";
if(window.forge === undefined) {
vendor = "/"+vendor;
app = "/"+app;
}
addScript(vendor, function() {
addScript(app, function() {
require('initialize');
});
});
</script>

no device ready and no console.log with xcode using cordova 1.5

This is all the code I have and I do not get neither the logs in xcode nor the deviceReady event (which I don't get on any other platform either. On Ubuntu+Android+Eclipse I do get the console logs, but no deviceReady. nor in chrome )
The js/cordova-1.5.0.js exists and being loaded as indicates an alert statement i've put in there.
Any clues where should I look ?
Thanks in advance ;)
<div id="d"></div>
<script>
function foo() {console.log('test'); document.getElementById('d').innerHTML += 'called';}
window.setTimeout(foo, 5000);
window.setTimeout(foo, 15000);
window.setTimeout(foo, 25000);
window.setTimeout(foo, 35000);
alert('hi');
console.log('non timed console.log');
</script>
<script src="js/cordova-1.5.0.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
alert('deviceReady');
//somewhy this never happens
}
</script>
Console.log works only after deviceReady event
Phonegap uses different phonegap.js files for android and ios, and only the
android one is distributed with the downloadable archive. Read
Dhaval's comment to learn where to get the ios version.
I used Weinre for debugging and almost missed that it overrides the console.log method,
therefore console.log doesn't work with weinre
As Alex pointed out, console.log is not available until after your PhoneGap device is ready. By calling it too soon, you're triggering a reference error.
Remove ALL of your existing javascript, and try this instead (replacing the alert on the second-last line with your own custom code):
var app = {
// denotes whether we are within a mobile device (otherwise we're in a browser)
iAmPhoneGap: false,
// how long should we wait for PhoneGap to say the device is ready.
howPatientAreWe: 10000,
// id of the 'too_impatient' timeout
timeoutID: null,
// id of the 'impatience_remaining' interval reporting.
impatienceProgressIntervalID: null,
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// `load`, `deviceready`, `offline`, and `online`.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
// after 10 seconds, if we still think we're NOT phonegap, give up.
app.timeoutID = window.setTimeout(function(appReference) {
if (!app.iAmPhoneGap) // jeepers, this has taken too long.
// manually trigger (fudge) the receivedEvent() method.
appReference.receivedEvent('too_impatient');
}, howPatientAreWe, this);
// keep us updated on the console about how much longer to wait.
app.impatienceProgressIntervalID = window.setInterval(function areWeThereYet() {
if (typeof areWeThereYet.howLongLeft == "undefined") {
areWeThereYet.howLongLeft = app.howPatientAreWe; // create a static variable
}
areWeThereYet.howLongLeft -= 1000; // not so much longer to wait.
console.log("areWeThereYet: Will give PhoneGap another " + areWeThereYet.howLongLeft + "ms");
}, 1000);
},
// deviceready Event Handler
//
// The scope of `this` is the event. In order to call the `receivedEvent`
// function, we must explicity call `app.receivedEvent(...);`
onDeviceReady: function() {
app.iAmPhoneGap = true; // We have a device.
app.receivedEvent('deviceready');
// clear the 'too_impatient' timeout .
window.clearTimeout(app.timeoutID);
},
// Update DOM on a Received Event
receivedEvent: function(id) {
// clear the "areWeThereYet" reporting.
window.clearInterval(app.impatienceProgressIntervalID);
console.log('Received Event: ' + id);
myCustomJS(app.iAmPhoneGap); // run my application.
}
};
app.initialize();
function myCustomJS(trueIfIAmPhoneGap) {
// put your custom javascript here.
alert("I am "+ (trueIfIAmPhoneGap?"PhoneGap":"a Browser"));
}
I know the question was asked 9 month before but I stumbled over the same problem.
If you want debug messages to appear in the weinre console you have to call:
window.cordova.logger.useConsole(false);
after deviceready.
Update:
It seems that you need luck to get console messages into weinre - thats bad :(

Resources