I have a couple of scripts that don't work anymore although I didn't make any change.
I don't spend a lot of time programming these last month so I didn't notice it right away...
Here is a simplified code that used to work and that doesn't, I can't figure out my error.
The HTML part is entirely built on server side since it's a very simple code (runs from a spreadsheet).
function myFunction() {
var doc = '<body style="font-family:arial,sans;font-size:12pt">';
doc+='<select id="target" multiple style="font-family:arial,sans;font-size:12pt">';
doc+='<option value="1">choice 1</option><option value="2">choice 2</option><option value="3">choice 3</option></select><br><br>';
doc+='<input type="button" onClick="processJS()" style="background:#BFA;font-size:12pt" value="Validate"/>';
doc+='<script>function processJS(){var e=document.getElementById("target");var values=Array.from(e.selectedOptions).map(option => option.value);';
doc+='console.log(JSON.stringify(values));google.script.run.withSuccessHandler(function(msg){ window.alert(msg);google.script.host.close;}).processGSTest(values)};</script>';
doc+='</body>';
var ui = HtmlService.createHtmlOutput(doc).setWidth(500).setHeight(250);
SpreadsheetApp.getUi().showModelessDialog(ui, "test");
}
function processGSTest(values){
Logger.log(JSON.stringify(values));
return "processGSTest ok";
}
I get an error in JS console like this when I hit "validate" :
the HTML rendered window looks like this :
EDIT
Following comments (thanks again) I've got a few more informations :
when using another browser the scripts works fine
when using chrome and adding an withFailureHandler it still fails with the same console message without handling the failure (Chrome Version 81.0.4044.122 (Build officiel) (64 bits) on Mac OS High Sierra)
when calling the same function from a custom menu the script works fine even in the same Chrome session
conclusion of this edit : I don't understand the issue :)
Since this post is about a very specific case that does not seem to be reproductible I answer it so it doesn't stay open indefinitely.
In the same time I'll post an issue report on the tracker.
Here is the script I use to show the issue.
The main function (myFunction) reports an error when called from the script editor but works when called from the menu...
This happens only on Chrome Version 81.0.4044.122 (Build officiel) (64 bits) on Mac OS High Sierra 10.13.6, it works normally on Safari, Firefox and even Chrome on Windows 10.
(It works also normally on the same version of Chrome under Mac OS 10.10.5 !! )
function myFunction() {
var doc = '<body style="font-family:arial,sans;font-size:12pt">';
doc+='<select id="target" multiple style="font-family:arial,sans;font-size:12pt">';
doc+='<option value="1">choice 1</option><option value="2">choice 2</option><option value="3">choice 3</option></select><br><br>';
doc+='<input type="button" onClick="processJS()" style="background:#BFA;font-size:12pt" value="Validate"/>';
doc+='<script>function processJS(){var e=document.getElementById("target");var values=Array.from(e.selectedOptions).map(option => option.value);';
doc+='console.log(JSON.stringify(values));google.script.run.withFailureHandler(function err(){window.alert("error triggered by withFailureHandler");})';
doc+='.withSuccessHandler(function(msg){ window.alert(msg);google.script.host.close();}).processGSTest(values)};</script>';
doc+='</body>';
var ui = HtmlService.createHtmlOutput(doc).setWidth(500).setHeight(250);
SpreadsheetApp.getUi().showModelessDialog(ui, "test");
}
function processGSTest(values){
Logger.log(JSON.stringify(values));
return "processGSTest ok";
}
function onOpen(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name: "test", functionName: "myFunction"}]
ss.addMenu("test",menuEntries);
}
I created a shared spreadsheet for anyone that would want to play with it (read only, make a copy to use)
Related
Is it possible to tell if another Chrome tab is using webkitSpeechRecognition?
If you try to use webkitSpeechRecognition while another tab is using it, it will throw an error "aborted" without any message. I want to be able to know if webkitSpeechRecognition is open in another tab, and if so, throw a better error that could notify the user.
Unless your customer is on the same website(you could check by logging the ip/browserprint in database and requesting by json) you cannot do that.
Cross domain protection is in effect, and that lets you know zilch about what happens in other tabs or frames.
I am using webkitSpeechRecognition for chrome ( does not work on FF) and I faced same issues like multiple Chrome tabs. Until the browser implement a better error message a temporary solutions that work for me:
You need to detect when a tab is focused or not in Chrome using
Javascript.
Make javascript code like this
isChromium = window.chrome;
if(isChromium)
{
if (window.addEventListener)
{
// bind focus event
window.addEventListener("focus", function (event)
{
console.log("Browser tab focus..");
recognition.stop();// to avoid error
recognition.start();
}, false);
window.addEventListener("blur", function (event)
{
console.log("Browser tab blur..");
recognition.stop();
}, false);
}
}
There's a small workaround for it. You can store the timestamp in a variable upon activating SpeechRecognition and when it exits after a few seconds of inactivity, it will be compared to a timestamp since the SpeechRecognition was activated. Since two tabs are using the API simultaneously, it will exit immediately.
For Chrome, you can use the code below and modify it base on your needs. Firefox doesn't support this yet at the moment.
var transcriptionStartTime;
var timeSinceLastStart;
function configureRecognition(){
var webkitSpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
if ('webkitSpeechRecognition' in window) {
recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onend = function() {
timeSinceLastStart = new Date().getTime() - transcriptionStartTime;
if (timeSinceLastStart < 100) {
alert('Speech recognition failed to start. Please close the tab that is currently using it.');
}
}
}
}
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition
I'm currently working on writing some automated tests for a web app, using WebDriverJs and Mocha. When I remove anything relating to Mocha, it runs fine and does exactly what I'm expecting. However, as soon as I introduce the mocha elements into my code, Chrome will open, but then won't load the url and the test times out.
The code I'm using (with mocha implemented) is as follows:
"use strict";
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().usingServer().withCapabilities({'browserName': 'chrome' }).build();
before(function() {
driver.get('http://127.0.0.1:3000/');
});
test.describe('Login', function() {
test.it('should work', function()
{
var passLoginTest = require('./PassLoginTest');
passLoginTest(webdriver, driver).then(function(loggedIn){
assert.isTrue(loggedIn, 'successfully logged in');
});
driver.quit();
});
});
I've also tried using driver.get('http://127.0.0.1:3000/); outside of a before block, but it had the same result. I'm using Mocha v. 2.2.1 and Webdriver 2.45.1.
I ran into this too, also when using jasmine instead of mocha.
I experimented a bit with the versions of mocha and selenium-webdriver.
It turns out version 2.43 of selenium webdriver and up have this issue, below works well for me. So I settled on the last version that works ok. My package.json now has
...
"selenium-webdriver": "~2.42.1",
"mocha": "~2.2.4",
...
You should not be calling before "naked" like you do. You should do like you do with describe and it and use the version that is provided by selenium-webdriver/testing so:
test.before(function() {
driver.get('http://127.0.0.1:3000/');
});
The version of these calls provided by selenium-webdriver/testing are modified to wait for the driver to do its work before moving on. The "stock" (which I called "naked" above) version of these calls would require at a minimum that you return a promise or that you use a callback.
Our chrome extension does not work correctly anymore since version 37.0.2062.103 (It used to work correctly on chrome version 36.0.1985.143).
Specifically, the debugger API has stopped working for us when we use the DOMDebugger.
See the attached code: (background.js)
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
if( changeInfo.status == "loading" && tab.active){
var debugId = {tabId:tabId};
chrome.debugger.attach(debugId, '1.0', function() {
chrome.debugger.sendCommand(debugId, 'Debugger.enable', {}, function() {
chrome.debugger.sendCommand(debugId, "DOMDebugger.setEventListenerBreakpoint", {'eventName':'click'},
function(result) {
console.log('registering click');
});
});
});
}
});
chrome.debugger.onEvent.addListener(onEvent);
function onEvent(debuggeeId, method,params) {
if(method=="Debugger.paused"){
console.log('DONE!');
}
};
The extension successfully starts the debugger. we get the yellow debugger ribbon.
We also see the 'registering click' msg in the console. the result argument is an empty object {} (line 8).
However upon clicking on a button that has a click event listener nothing happens.
It used to work without any issues.
It seems like it regressed with https://codereview.chromium.org/305753005. One needs to call "DOM.enable" for it to work now. On the Chrome side, we should implicitly enable DOM domain upon setEventListenerBreakpoint for backwards compatibility. Unfortunately it already squeezed into the stable release.
I'm trying to run the "Using IndexedDB" sample code on https://developer.mozilla.org/en-US/docs/IndexedDB/Using_IndexedDB
Right out of the gate I stumble with the first line of code:
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
Using Firebug I see that window.indexedDB is undefined as expected for FF 15, window.webkitIndexedDB is undefined as expected (FF isn't webkit) but window.mozIndexedDB is null but not undefined. If it's null that tells me it exists but doesn't have a valid value/isn't initialized.
This is with Firefox 15.0.1 on OSX 10.6.8 and Ubuntu 12.04. Can somebody tell me why I'm not able to see/use window.mozIndexedDB? Am I doing something wrong?
For completeness, here's my JavaScript file:
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
var request = window.indexedDB.open("MyTestDatabase", 3);
var db;
request.onerror = function (event) {
alert("Oops, request.onerror");
};
request.onsuccess = function (event) {
// Do something with request.result!
alert("Made it to request.onsuccess");
db = request.result;
};
// This event is only implemented in recent browsers
request.onupgradeneeded = function (event) {
alert("Made it to request.onupgradeneeded");
};
db.onerror = function (event) {
alert("Database error (db.onerror): " + event.target.errorCode);
};
My original HTML5 application uses jQuery Mobile & REST WS. In development I would run it directly from the file system and it works fine. For sharing with coworkers I have it running behind Apache httpd.
While adding the IndexedDB, I was trying to test by viewing files from the file system via the browser. It didn't work and that's what caused me to go back to square one and try running the example code from Mozilla.
It appears IndexedDB requires a domain even if it's localhost. I simply placed my code under public_html and viewed it via httpd/localhost and it's working perfectly.
I've created a Greasemonkey script which replaces a page function:
(function() {
var oldFunc = func;
func = function() {
oldFunc();
// other stuff
};
)();
I had always intended this script to work in both Gresemonkey and Chrome and had read that Chrome doesn't support unsafeWindow, so have been injecting the script into the page by converting the function to a string and using setTimeout:
setTimeout("(function(){var old=func;func=function(){old();/*other stuff*/}}())", 0);
This works perfectly well in Greasemonkey, but gives me absolutely nothing in Chrome. It clearly isn't firing, but nothing appears in the log, either. I have tried a number of other injection styles, but can't get anything to work. (For testing, I also added an alert() to the top of the function.)
setTimeout(..., 0) — nothing
Running the function in-scope, without injection into the page — no alert, but "func is not defined" in console
document.href = "javascript:..." — nothing
document.body.addEventListener("load", ...) — nothing
All of these are with #run-at document-end.
Unfortunately, this being my first Chrome userscript, I'm at a loss as to how to debug it, even after an hour or so of Googling and poking around SO. Any help?
Actual script, currently working in Greasemonkey: http://pastebin.com/HtLVjYHg
In the end, the only technique I found which worked in Chrome was to create a <script> node using DOM methods. Fortunately, this seems to work equally well in Firefox and Opera and is made fairly painless by <func>.toString():
function embed() {
var oldFunc = window.func;
window.func = function() {
oldFunc();
// other stuff
};
}
var inject = document.createElement("script");
inject.setAttribute("type", "text/javascript");
inject.appendChild(document.createTextNode("(" + embed + ")()"));
document.body.appendChild(inject);
Final script: http://userscripts.org/scripts/review/84394