Closure Library ondevicemotion never fired - javascript

Dear Javascript programmers,
Google's Closure Library is always good for driving people crazy. I hope you can help me on this issue:
I want to catch the ondevicemotion-Event by javascript within a function within the Closure lib.
Without Closure everything works fine with the following code which I grabbed from this page (thanks to the author): http://www.peterfriese.de/how-to-use-the-gyroscope-of-your-iphone-in-a-mobile-web-app/
The following snippet shows "my" code:
if (window.DeviceMotionEvent != undefined) {
console.log("DME");
window.ondevicemotion = function(e) {
console.log("ODM");
// handle events like e.rotationRate
...
}
}
This works perfectly in a standalone html page. Both console.logs are triggered.
In contrast, Closure seems to have a problem with window.ondevicemotion = function(e) { because the console logs "DME" but not "ODM".
There are no compiler warnings or errors.
Has anybody recognized such a problem, too? I sadly have no idea why Closure acts so stupid (more probably I am so stupid). ;-)
Thanks for reading! Any help appreciated!

Running in ADVANCED_COMPILATION, the Closure Compiler minimized and obfuscated window.ondevicemotion for me, so I'll assume that is your problem as well. There are two ways to step around this:
1. Use bracket notation to set / access the property.
The Closure Computer will not rename any properties that are referenced via the bracket notation. The following should not get obfuscated (though, potentially, it could get rewritten as window.ondevicemotion):
window['ondevicemotion'] = function(event) { ... }
2. Use an extern to let the compiler know not to rename this property.
Similar to the situation above, the Closure Compiler takes a hint and doesn't rewrite the property, leaving it as is. This, however, has a nice benefit of giving you some type checking, since you're defining what the signature of the extern is to the Closure Compiler:
/**
* #param {goog.events.Event} event
*/
window.ondevicemotion = function(event) {};
The decision of which one to use is ultimately yours. In this scenario I would most likely go for the second option and only go back to the first if there was some reason you could not use externs.

Related

How can I detect use of invalid properties in javascript?

I'm learning Javascript and I wrote the following code:
if (mystring.len > 0) {
// do stuff
}
I accidentally used .len instead of .length. To my surprise, no error was raised. mystring.len returned undefined and this made the comparison fail but the code kept right on running. I would prefer an actual error to be raised so I can fix the code. Adding "use strict" didn't help, nor did jslint.
I know there are ways to actively check whether or not a property exists, but that's not what I'm looking for. I want Javascript to tell me when I've made a typo in a property name.
Is there a way to cause Javascript to give an error in this case?
Nope - that is how JavaScript works and it's incredibly useful. Who is to say that checking len is something that needs fixing? Consider:
if(mystring.len === undefined) {
mystring.len = "Test";
}
The best you can do is to simply check that the thing is defined before using it:
if(mystring.len !== undefined) {
}
I appreciate the strangeness, and how it doesn't feel robust (having originally come from a C# background) but there isn't a lot you can do unfortunately. The fact that JavaScript is case sensitive makes this even more frustrating. You will learn to live with it though!
If you really really wanted to run some static analysis then you could considering creating a transpiler (e.g. Babel) extension to run this sort of analysis - but it would get really difficult if you ever expected something to be undefined which I find is common place.
edit
Here's a real example that I'd use where undefined is useful. I'm working with a library that needs to move stuff from one location to another. It can't do that unless the original location has been specified, so I might write something like the following, initializing values if I don't have them for some reason:
function update(node) {
if(node.x === undefined) { node.x = 0; }
node.y = node.y || 0; // This is the shorthand way I'd actually write it
// Do some other stuff
};
"use strict" (in my experience) is used so that variables that aren't explicitly declared/instantiated that are then referenced will throw errors (else, JS would just make a new var on the fly). So that wouldn't help here.
This sounds like an error that would typically be picked up by a compiler in other languages, but since JS is interpreted, you won't have that kind of explicit error checking unless you're in a beefy IDE. Are you using a text editor or something to write JS?
Thats not the way JavaScript considers your above code. Every variable in JS is an object. So, when you do mystring.len, its actually trying to access the len property of mystring obj and when it doesn't find that property, it will return undefined - which is how it should be. Thats why you will not be able to find any error using JSLint.
Just to give you an example -
var myObj = {name: 'Hello', id: 1};
console.log(myObj.name); // Returns 'Hello'
console.log(myObj.text); // 'undefined'
In order to prevent such code from giving you any errors, you can easily use the hasOwnProperty() method like follows-
if(myObj.hasOwnProperty('text')) doSomething();
Since myObj doesn't have any property text, the doSomething() function will never be called.
This is the behaviour of JavaScript as mentioned by many/all answers. However there is an option to prevent new properties you might want to try:
Object.seal https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
The simple answer is JavaScript is not ment to be typesafe...You shouldn't check it, but if you still want to check you can do it by:
if ('len' in mystring){
}
You should look into Typescript if you ask this question...

JavaScript getter defined as an array instead of a function?

I can't reconcile the following with any of the JavaScript documentation I've read. Can somebody please shed some light?
The following snippet is taken from file panelUI.js in the Mozilla repository.
const PanelUI = {
/** Panel events that we listen for. **/
get kEvents() ["popupshowing", "popupshown", "popuphiding", "popuphidden"],
// more properties...
_addEventListeners: function() {
for (let event of this.kEvents) {
this.panel.addEventListener(event, this);
}
// more code...
},
// more properties...
Everything I've read about JS defines a getter as essentially a function (or "a method that gets the value of a specific property" and "The get syntax binds an object property to a function that will be called when that property is looked up"), so I'm a bit baffled to see an array literal where I would expect to find the body of function kEvents().
What does it mean in JS to have a function name followed by an array literal (in general or as part of a get definition)?
How would you write code that is functionally equivalent to the above, but does not use this somehow odd syntax?
I assume this is a consequence of SpiderMonkey's non-standard and deprecated support for expression closures.
this isn't valid JavaScript in any way... unless Firefox is allowing it as an alternative syntax for some reason.
but if you tried to run this or similar code in a browser like chrome, or even trying to compile it using Babel and ES6, it fails.
How would you write code that is functionally equivalent to the above, but does not use this somehow odd syntax?
An "equivalent" syntax appears to be to wrap the data in curly braces and return it:
get kEvents() {
return ["popupshowing", "popupshown", "popuphiding", "popuphidden"];
},
I would guess that the example code returns the same array instance every time, whereas my code is going to generate a new array every time it's called.
I imagine that the listed line is a non-standard syntax that mozilla has implemented but that is not associated with any current spec. Oftentimes with these sorts of features the browser development community pushes a browser to implement a new feature to see if it's worthwhile for standardization. It could have been a proposed syntax that was later dropped as well
That all said, this is speculative, as I've never seen a standard with that syntax in it.

Is it safe to rename document variable in javascript

I noticed that Google Closure Compiler did not rename document to something like d to reduce space.
I cannot think of a case where this would break the code (ie where document points to something else down the road). Actually the same goes for window.
Is there a reason for protecting document this way?
== EDIT ==
By renaming it I was thinking reassigning it. Example below.
var d=document;
var obj1=d.getElementById("obj1");
var obj2=d.getElementById("obj2");
... // with enough uses of document so it makes to reassign it size-wise.
Closure-compiler does not perform this "optimization" by default for the simple reason that it produces LARGER source when used with gzip. You can enable this optimization by turning on the AliasExternals pass using either the Java API or a custom build.
See https://code.google.com/p/closure-compiler/source/browse/src/com/google/javascript/jscomp/AliasExternals.java#38
What happens?
ProblemFactory's guess is correct.
This is a //TODO in the closure compiler source code. If we didn't preserve document and window and instead ran them over with d for example, at the moment the closure compiler does not know if it's overriding a global from another file. Like the comments say this will be resolved in the future at which point.
Enough words, show me the source!
If we check the closure compiler source code inside VariableReferenceCheck.java we can find the following:
private class ReferenceCheckingBehavior implements Behavior {
#Override
public void afterExitScope(NodeTraversal t, ReferenceMap referenceMap) {
// TODO(bashir) In hot-swap version this means that for global scope we
// only go through all global variables accessed in the modified file not
// all global variables. This should be fixed.
// Check all vars after finishing a scope
for (Iterator<Var> it = t.getScope().getVars(); it.hasNext();) {
Var v = it.next();
checkVar(v, referenceMap.getReferences(v).references);
}
}
If we check the hot-swap algorithm itself we can see that:
// Note we use the global scope to prevent wrong "undefined-var errors" on
// variables that are defined in other JS files.
So, we can see that this is just the closure compiler not understanding the code of globals across multiple files well enough to make that replacement. You can always do the replacement yourself :)
I think document is standardized, always-global variable. To use the same way d it has to be global also, thus global namespace will have another "junk" variable.
It could be dangerous for not aware developers (which wont be aware of that thus it is not standard variable).

How to use "Go to Declaration" with NetBeans and javascript?

I know we can use Ctrl+Click or Ctrl+B in NetBeans, but it doesn’t work for me when I’m writing javascript files.
And I’m not the only one (sadly that question has no reply).
I can see the functions on the Navigator, but I can’t use “Go to declaration”.
I’m declaring my functions this way:
function anyName(params...) { ... }
I tried changing to this style:
var anyName = function (params...) { ... }
But that didn’t work either.
I’m using Netbeans 6.9.1.
More info:
NetBeans supports “Go to declaration” in javascript.
As I said, the function is recognized because I can see it in the Navigator.
I can use Ctrl+O and then search for my function, and NetBeans can find it when I do that. I’m using this right now as a poor replacement for “Go to declaration”.
I’ve noticed that I don’t have code completion either. Following the above example, if I write “an” (Ctrl+Space) I can see a lot of functions and methods but I can’t find my function (anyName).
I think I’m doing something really wrong, but I don’t know what.
I think the short answer is NetBeans doesn't have a good parser for JavaScript. JS is such a loosely typed language, it could be incredibly difficult to "Go To" the actual definition of a function. Take these examples:
function callStuff(myFunc)
{
myFunc(); //Where does this go?
}
callStuff(function () { window.alert(123); });
Or:
var x = {
X: function () { },
Y: function () { },
};
x.Z = function () { };
x.Y(); //Where do I go?
x.Z(); //How about this?
Or maybe:
string s = "window.alert(123);";
var callback = Function(s);
callback(); //Now we just made a function with a string, weird..
So as you can see, a JavaScript IDE would need to have an immense amount of knowledge on the run-time execution of your script to figure out exactly where a function was defined. There's a few IDEs that fake it pretty well if you use standard syntax or very obvious function declarations, but I've yet to see anything incredibly useful in this area. It's most likely not really something NetBeans has made an effort to support, since it's such a Java-centric IDE.
The problem seems to be in defining everything as “global”. If you work in your own namespace — that is, create a global object and define everything there — then Netbeans can understand better where your code is and can also give you type hints.

Intercepting global variable definition in javascript

I'm trying to tidy up some javascript code and one of the steps is removing all useless (or plain wrong) global variables that have slipped in from errors like:
for (prop in obj) { ...
instead of
for (var prop in obj) { ...
JSLint helps a bit in finding out this nastiness, but it is not 100% foolproof when the nastiness happens at runtime.
I already tried to add some monitoring code that routinely checks the global scope logging to the console if some new variable is detected, and that helped some more, but when it tells me that a new global variable named "i" has been detected ... well, it's a mess finding out where that happened in thousands of lines of code.
So here we come: is there a better way/tool/script/whatever to find the little pests?
My dream is something like a Firebug plugin that stops the execution whenever a new global variable is created...
Thanks!
You may find this bookmarklet useful.
Also, checkout this answer: How to detect creation of new global variables?
You can now intercept variable definition as explained on this similar question
window.__defineSetter__('sneakyVariable', function() {
debugger
})
and you'll be able to find where it was defined
I wonder if you could set a timeout to create a list of all global variables and then compare that against the last time the timeout fired. I found this on Stack Overflow, and maybe you could use this code in conjunction with a setTimeout() to get what you want.
Blockquote
Yes and no. "No" in almost every situation. "Yes," but only in a limited manner, if you want to check the global scope. Take the following example:
var a = 1, b = 2, c = 3;
for ( var i in window ) {
console.log(i, typeof window[i], window[i]);
}
Stack Overflow link: Getting All Variables In Scope
well, I wrote this long time ago, so code sucks, but it does the job: https://gist.github.com/1132193
paste in the firebug console or include as a script.
You say, you are trying to tidy up some code.
In that case - use IDE, like NetBeans PHP (free) or JetBrains WebStorm (30$). They both color global variables, and do lots of other useful stuff ;)
If your polling script will still detect creation of global variables - trace down offending functions, and make them suffer ;) Eventually, the code will become clean.

Categories