JS Closure Compiler - Dont change the function-names - javascript

i use the http://closure-compiler.appspot.com/home to compress my code.
MY JS File *EDIT:*
function test_it()
{
// some code
}
MY HTML Code
<div onclick="test_it" />test</div>
My problem is that the compressor rename my function.
When i click (after the compression) on the div i get the error "test_it is not defined". That makes sense coz the function has a new "short" name now.
Is it possible to deactivate "in the Advanced mode" the "rename functions" function?
Or is there a other solution?
Thanks in advance!
Peter

The solution is to bind the click event through javascript:
function test_it() {
// some code
}
document.getElementById("test").onclick = test_it;
HTML:
<div id="test">test</div>
This way the compiler will still change the name of the function (saves space), but it will also change the name of the reference -> problem solved.

Your function has errors in it. You have a closing ) at the end and a ; which is not necessary. It should be:
function test_it()
{
// some code
}
Now if you use the Simple mode you won't have any problems. Be careful with the Advanced mode though as it might perform optimizations and remove this function if not used.

Related

How to deal with DOM elements?

I am learning about writing custom JavaScript for my Odoo 10 addons.
I've written the following piece of code:
odoo.define('ioio.io', function(require) {
'use strict'
const e = $('div.o_sub_menu_footer')
console.log('--testing--'.repeat(7))
console.log(e)
// the "Powered by Odoo" down the secondary menu
e.remove()
})
The code is well loaded and I can see my testing string in the console.
However when this code is being loaded before the target div, so e empty/not yet filled and thus its content is not removed.
Doing it manually from the console works.
My question is what is the right way to do that? And how to know exactly when the code gets executed?
You can
put your html code before the script tag in your file
use jQuery $(document).ready(...);
Place your script at the bottom of the <body> tag to make sure the DOM renders before trying to manipulate it.
This is an Odoo specific question, so you should use the Odoo standard way, which is via its base JS class. That class contains a ready() method which does exactly what you need.
In your case, to use that function, you need to require the class first. Then you can use ready().
Updating your code, it should look like this:
odoo.define('ioio.io', function(require) {
'use strict'
// require base class
var base = require('web_editor.base');
//use its ready method
base.ready().done(function () {
// put all the code you want to get loaded
// once the DOM is loaded within this block
const e = $('div.o_sub_menu_footer')
console.log('--testing--'.repeat(7))
console.log(e)
// the "Powered by Odoo" down the secondary menu
e.remove()
});
})
While your accepted answer leads to the same outcome, you might want to update it to this one since this is the Odoo way. It's generally advised to work within the Odoo framework as much as possible and customise only if really needed. (Though it can be tough to learn what features Odoo already provides because of its poor documentation.)

JavaScript - how to use Setters and Getters in to create a listener

Before this gets marked as a duplicate: I have read posts all day about this so I know there are tons of similar questions on SO but none that I've seen so far go into the details that I need to understand.
Having said that, there are no good commented examples of how the process works. Could someone answer the following question with well a well-commented example so I could finally understand this ability?
I have a function that I want to call in one file but I need to make sure that another event in another file has already happened before I call it. These files have no connection (one is an angular 2 TypeScript file that starts the app and the other is a JS file that manages a hopscotch tour). I understand that I will need to use a global variable and I believe that the best solution I've read is going to involve using setters and getters. All examples I've seen of this seem to assume that it's just intuitive and leave out the part where I get to understand how it's working. Maybe it is intuitive but I'm not making the leap yet.
Global variable in TypeScript file:
global_variable = false;
Function I want to call in JavaScript file based on the listener:
function call_if_other_function_finishes() {
if (global_variable === true) { // I have the global already created
// run hopscotch tour
}
} // how do I turn this into a listener?
The function I need to have finished first in TypeScript file:
function someFunction() {
// run its code
GlobalFile.global_variable = true; // Should trigger the listener.
}
Thanks in advance!!
One solution is to just define the function as you do in your example and then run it when you need it:
function someFunction() {
// run its code
call_if_other_function_finishes() // it's globally defined anyway
}

Debugging Javascript functions in Firebug

I am trying to debug legacy scripts with Firebug. As per my knowledge (Which I got yesterday)
we use Step over (F10) to debug line by line and Step into (F11) to dig into JS function.
But when I use Step into on any JS function call, it takes control to next line. I want to see what is hidden inside the function. How can we do it ?
I kept break-point inside the function and then tried Step into then it takes control inside the function body. But it is tedious to find each function method and set break-point.
Is there any other way to do it ? or which is the right way ?
For example :
i2b2.ONT.ctrlr.FindBy = {
clickSearchName: function() {
// do some stuff
i2b2.ONT.ctrlr.FindBy.doNameSearch(search_info); // I tried Step into here
// some more stuff
}
doNameSearch: function(inSearchData) {
// If I set break-point here then only I can debug it
// or it directly takes control to `// some more stuff` in `clickSearchName:function`
}
}
PS: It also more external JS function calls.
Thanks,
Ajinkya.
"Step into" will step into the function if there is JS source for the function. If not (like for document.getElementById("foo"), it will step over it since it doesn't have anything that it understand to step into.
If you can point us to a working example where you are having the problem (either a jsFiddle reduction of the problem or a working web page) with instruction on where the relevant code is, we can probably help more.
Judging by your code example, I'm wondering what you're trying to step into. The line of code that starts with clickSearchName defines a function. It doesn't execute it. So, it won't go into that function until some later code actually calls clickSearchName. So, perhaps you're breaking on the definition of the function and trying to step into the function when it isn't being executed. That's just a guess though since we don't have a working example to try ourselves.
Add the line debugger; to your code at the place where you want to break into the debugger, it's a JavaScript keyword, which should do what you want. Just remember to take it out when you're done debugging your code.

Weird Object Error in Javascript

First, I'm not a javascript developer so I don't have a great deal of experience in this if any.
I have a footer I'm inserting into an HTML page using jQuery that has the following code in it that per the client "NEEDS TO BE THERE".
<script language="JavaScript"><!--
/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code=s.t();if(s_code)document.write(s_code)//--></script>
<script language="JavaScript"><!--
if(navigator.appVersion.indexOf('MSIE')>=0)document.write(unescape('%3C')+'\!-'+'-')
//--></script>
I don;t really have to worry about anything except this s.t(); line of code. I need to write a dummy Object or whatever else and include it in the header that doesn't do anything per se except prevent a javascript error from occurring.
So really I need "s" the object to be instantiated and have a function "t" attached to it that basically does nothing.
Any help is appreciated. This isn't something I want to do but given the budget and project constraints of the client I just need for this to work without a javascritp error.
thanks if you can help.
Using javascript prototype:
function s () {
}
function doSomething () {
}
s.prototype.t = doSomething;
edit: typo
var s = {
t: function(){}
};
See it in, hmm, action: http://jsbin.com/oboju
In case you're worried s is defined and don't want to override it, you can check for it first (this doesn't cover the case s.t is defined but isn't a function):
if(!s){ // check if s exists
var s = [];
}
if(!s.t){ // check if s has t
s.t = function(){};
}

Why is my JavaScript function sometimes "not defined"?

I call my JavaScript function. Why do I sometimes get the error 'myFunction is not defined' when it is defined?
For example. I'll occasionally get 'copyArray is not defined' even in this example:
function copyArray( pa ) {
var la = [];
for (var i=0; i < pa.length; i++)
la.push( pa[i] );
return la;
}
Function.prototype.bind = function( po ) {
var __method = this;
var __args = [];
// Sometimes errors -- in practice I inline the function as a workaround.
__args = copyArray( arguments );
return function() {
/* bind logic omitted for brevity */
}
}
As you can see, copyArray is defined right there, so this can't be about the order in which script files load.
I've been getting this in situations that are harder to work around, where the calling function is located in another file that should be loaded after the called function. But this was the simplest case I could present, and appears to be the same problem.
It doesn't happen 100% of the time, so I do suspect some kind of load-timing-related problem. But I have no idea what.
#Hojou: That's part of the problem. The function in which I'm now getting this error is itself my addLoadEvent, which is basically a standard version of the common library function.
#James: I understand that, and there is no syntax error in the function. When that is the case, the syntax error is reported as well. In this case, I am getting only the 'not defined' error.
#David: The script in this case resides in an external file that is referenced using the normal <script src="file.js"></script> method in the page's head section.
#Douglas: Interesting idea, but if this were the case, how could we ever call a user-defined function with confidence? In any event, I tried this and it didn't work.
#sk: This technique has been tested across browsers and is basically copied from the Prototype library.
I had this function not being recognized as defined in latest Firefox for Linux, though Chromium was dealing fine with it.
What happened in my case was that I had a former SCRIPT block, before the block that defined the function with problem, stated in the following way:
<SCRIPT src="mycode.js"/>
(That is, without the closing tag.)
I had to redeclare this block in the following way.
<SCRIPT src="mycode.js"></SCRIPT>
And then what followed worked fine... weird huh?
It shouldn't be possible for this to happen if you're just including the scripts on the page.
The "copyArray" function should always be available when the JavaScript code starts executing no matter if it is declared before or after it -- unless you're loading the JavaScript files in dynamically with a dependency library. There are all sorts of problems with timing if that's the case.
My guess is, somehow the document is not fully loaded by the time the method is called. Have your code executing after the document is ready event.
Verify your code with JSLint. It will usually find a ton of small errors, so the warning "JSLint may hurt your feelings" is pretty spot on. =)
A syntax error in the function -- or in the code above it -- may cause it to be undefined.
This doesn't solve your original problem, but you could always replace the call to copyArray() with:
__args = Array.prototype.slice.call(arguments);
More information available from Google.
I've tested the above in the following browsers: IE6, 7 & 8B2, Firefox 2.0.0.17 & 3.0.3, Opera 9.52, Safari for Windows 3.1.2 and Google Chrome (whatever the latest version was at the time of this post) and it works across all browsers.
If you're changing the prototype of the built-in 'function' object it's possible you're running into a browser bug or race condition by modifying a fundamental built-in object.
Test it in multiple browsers to find out.
This has probably been corrected, but... apparently firefox has a caching problem which is the cause of javascript functions not being recognized.. I really don't know the specifics, but if you clear your cache that will fix the problem (until your cache is full again... not a good solution).. I've been looking around to see if firefox has a real solution to this, but so far nothing... oh not all versions, I think it may be only in some 3.6.x versions, not sure...
Solved by removing a "async" load:
<script type="text/javascript" src="{% static 'js/my_js_file.js' %}" async></script>
changed for:
<script type="text/javascript" src="{% static 'js/my_js_file.js' %}"></script>
Use an anonymous function to protect your local symbol table. Something like:
(function() {
function copyArray(pa) {
// Details
}
Function.prototype.bind = function ( po ) {
__args = copyArray( arguments );
}
})();
This will create a closure that includes your function in the local symbol table, and you won't have to depend on it being available in the global namespace when you call the function.
This can happen when using framesets. In one frame, my variables and methods were defined. In another, they were not. It was especially confusing when using the debugger and seeing my variable defined, then undefined at a breakpoint inside a frame.
I'm afraid, when you add a new method to a Function class (by prtotyping), you are actually adding it to all declared functions, AS WELL AS to your copyArray(). In result your copyArray() function gets recursivelly self-referenced. I.e. there should exist copyArray().bind() method, which is calling itself.
In this case some browsers might prevent you from creating such reference loops and fire "function not defined" error.
Inline code would be better solution in such case.
I think your javascript code should be placed between tag,there is need of document load

Categories

Resources