https://github.com/placemarker/jQuery-MD5
Requirements
None.
If jQuery is not available, the md5 function will be added to the global object
what does this mean?does md5.js need jquery or not?
No, it doesn't.
jQuery is an optional integration which allows you to compute the MD5 hash via the jQuery $ variable, like so:
var md5 = $.md5('value');
Because it's optional, when not present you will still be able to compute the hash, in the following way:
var md5 = md5('value');
You can infer that from the source code, which exports the function to the given scope. The scope is defined here:
// ...
}(typeof jQuery === 'function' ? jQuery : this));
If the jQuery is not defined as a function, the global this object will be used. This also means that the code will export the MD5 function to either jQuery or global scope but not both, which is likely why this answer has been down-voted.
Related
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).
I am using a jQuery plugin and running it through the Microsoft Ajax Minifier. My scripts work well for me, but now I am running into an issue with this plugin. The issue is that the plugin calls a function by its name using a string:
var s = (getCachedSortType(table.config.parsers, c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc");
Note the "sortNumeric" and "sortNumericDesc". This calls these functions:
function sortNumeric(a, b) {
return a - b;
}
function sortNumericDesc(a, b) {
return b - a;
}
This is the only location these functions are called so the IDE VS2010 doesn't think that the functions are being called from anywhere... They are conditionally via the code above.
**Here is the Problem**
When this gets minified, the string name of the function stays, but the function gets removed because it does not thing its getting referenced.
Is there any way to adjust the settings minifier to not do this?
I have also seen it change the names of the functions so
function testFunctionName(a,b)
Would become
function a
This would also cause a problem for situations like mine...
Please note, that I know it is bad code design to hard code function names like this. Like I said it is a plug-in that I am using. I would accept a solution that would call the function out right instead of by string, but I am always hesitant to modify plug-ins.
From documentation:
-evals:(ignore|immediate|safeall) specifies how eval statements are to be treated. This is an important switch to be aware of. By default Ajax Minifier will ignore any eval statements, which can break your minified code if it contains eval statements that reference named local variables or functions. This is because by default Ajax Minifier will also rename local variables and function, but it doesn’t modify the text passed to the eval function, so those references may break. If you minify code and it stops working properly, check the code for eval statements. If there are any, try specifying one of the other two –evals switch options. The “immediate” options will not rename any variables or functions within the same scope as any eval call; the “safeall” option will not rename any variables or functions not only in the same scope as any eval call, but also in any parent scopes. This will seriously impair the minification of your code, but should ensure that any calls to the eval function will work as expected. The default setting is ignoreall.
Then try -evals:immediate and if your code is still broken you have to use -evals:safeall (even if this will make your JavaScript files bigger).
UPDATE
If you're not using eval then you have to skip function renaming at all:
-rename:(all|localization|none) specifies whether or not to automatically rename local variables and functions. Global variables and functions are not automatically renamed, nor are property names. If “localization” is specified, only variables that do not start with “L_” will be renamed. The default value is all.
Just add -rename:none.
Use -unused:keep switch to retain unused functions. This, naturally, will prevent minifier from removing really unused code.
Use -rename switch to assign permanent names to functions that you call by name.
Just so there is no misunderstanding, this question is not about allowing for optional parameters in a JS function.
My question is motiviated by the jQuery parseXML function, which is defined in jQuery.js as follows:
// Cross-browser xml parsing
// (xml & tmp used internally)
parseXML: function( data, xml, tmp ) {
...
}
Within the body of the function, the parameters xml and and tmp are both assigned before they are used. That means they are being used as local variables, so the function could have been defined like this:
parseXML: function(data) {
var xml, tmp;
...
}
What is the benefit of doing it the first way, other than saving a few characters in the minified version of jQuery.js?
If we define two functions...
function a ( foo ) { }
function b ( foo, bar, baz ) {}
...they'll report different lengths...
console.log( [a.length, b.length] ); // logs [1, 3]
It's very rare to see this little known feature of javascript used.
But apart from shaving a couple of bytes off the minified file-size, this is the only other reason that I can think of.
In general, you might add unused parameters to a function to conform to some pre-agreed function signature, if you're going to pass this function to another function as a callback or continuation, and the API contract says "I call your callback with these parameters", and you don't need all the parameters to do what you want to do in the callback. (This would apply to any language, not just JavaScript.)
In this specific case, I don't know. How is parseXML used; is it called directly, or used as an argument to other functions which might expect a 3-argument function?
(xml & tmp used internally)
You misunderstand the meaning. They do not mean "internally" within the function. They mean internally within the library. The public API of this function has one parameter (data). The private API of this function has 3 parameters.
This is common throughout jQuery. In general these functions can work with and without side effects. The API without side effects is public and jQuery itself will pass in more parameters to cause side effects that you as a user should not be doing.
These variables are located immediately after defining a local copy of jQuery in the jQuery source.
// Map over jQuery in case of overwrite
_jQuery = window.jQuery
// Map over the $ in case of overwrite
_$ = window.$
One can read the comments and know the why... but
How do these lines of code do this?
Would adding something similar protect my personal namespace or is there more too it deeper in the source?
What is an example of something bad that could happen if this weren't in the source code?
If you look through the jquery.js file you will find that they start by saving the previous definition (line 31-32 v1.4.4):
// Map over the $ in case of overwrite
_$ = window.$,
Then if you call noConflict it just sets the value back (line 397-398)
noConflict: function( deep ) {
window.$ = _$;
You can add something similar to your own project to protect the name space. The concept holds for more than just javascript.
If these lines were not included, then you wouldn't be able to run jQuery and Prototype on the same page as both use the $ operator - nothing bad may happen, it's just that your code won't work and possibly cause errors.
How does jQuery protect overwriting jQuery and $
It doesn't (but see below). If you load jQuery, and then load something else that writes something else to those symbols, they won't be associated with jQuery anymore. Example:
HTML:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js"></script>
JavaScript:
window.onload = function() {
// Outputs false, because Prototype has overwritten it
display("Does $ === jQuery? " + ($ === jQuery));
// Outputs true, because Prototype has overwritten it
display("Does $('foo').id === 'foo'? " + ($('foo').id === 'foo'));
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
};
Live copy
But, it does seem to preserve them. How?
The answer is closures. It has a local reference, inside its scoping function, which is unconnected to the global reference (the property on window), so internally it doesn't care whether you overwrite those symbols. Of course, you care, if you overwrite both $ and jQuery, because if you do you have no way of calling jQuery. :-) But if you only overwrite $, that's not a problem, just use jQuery or if you don't like typing that (and let's face it, it's awkward), do this:
(function($) {
// Your usual jQuery code here using `$`,
// this code runs immediately
)(jQuery);
...which shadows the $ symbol locally within the anonymous function (which is defined and called at the same time). jQuery makes this particularly easy if you're using its ready event:
jQuery(function($) {
// Your usual jQuery code here using `$`,
// this code runs when the DOM is ready (see
// the `jQuery.ready` function).
});
If you were to include another library like prototype, which uses $, then jQuery needs to have a reference of both $ and window.jQuery in order to support the jQuery.noConflict() function, etc...
http://api.jquery.com/jQuery.noConflict/
$ is used because it is convenient, but this comes at the price that it may be used by more than one library.
Does that help?
Javascript doesn't have the means of providing the kind of protection you are looking for.
JQuery isn't "protecting" those variables. It's just copying the references $ and jquery into two other variables. The code you have read is equivalent to:
var obj1 = {}; /* create an empty object and reference it as obj1 */
var obj2 = obj1; /* made a second reference to that same object */
This code doesn't "protect" obj1. It's perfectly valid that your code later on changes the value of obj1:
obj1 = 'foo'; /* now obj1 references a string */
obj1 doesn't "magically retain its value"; after that line, it's just a string. But the object is still available in obj2.
The purpose of those lines is to be able to restore the original $ and jQuery global variables in case jQuery itself overrides them. It doesn't do anything to protect other code from overriding jQuery.
If you want to protect your own namespace, you can do a setInterval that checks if the global variable is still an instanceof your object (only if your object is protected inside a closure, otherwise it can be modified too). But, this isn't good practice, as the idea of javascript is to be able to extend and customize. Put the control in the hands of the developer, don't try and "lock in" your objects.
Currently I am working on a legacy web page that uses a ton of JavaScript, jQuery, Microsoft client JavaScript, and other libraries. The bottom line - I cannot rewrite the entire page from scratch as the business cannot justify it. So... it is what it is. Anyway, I need to pollute (I really tried not too) the global namespace with a variable. There are the three options I was thinking about -
Just store/retrieve it using a normal JavaScript declaration - var x = 0;
Use jQuery to store/retrieve the value in a DOM tag - $("body").data("x", 0);
Use a hidden form field, and set/retrieve the value with jQuery - $("whatever").data("x", 0);
Is there a better way? I looked at the existing pile of code, and I do not believe the variable can be scoped in a function.
You can create a namespace inside the jQuery object, like so:
$.mynamespace = {
myVar : "something",
myVar2 : "somethingElse"
};
or:
$.mynamespace = {};
$.mynamespace.myVar = "something";
$.mynamespace.myVar2 = "somethingElse";
Bear in mind, any plugin method named 'mynamespace' will be overwritten so be sure to use a sensible name.
For me the best way to handle this situation is to define an object in the window object:
window.my_config =
{
my_var1 : 1,
my_var1 : 2,
my_var1 : 3
};
This would keep your scope neat and clean. And whenever you would access the global using window.my_config anyone looking at the code would know that a global is being accessed.
You can create a hash in the global scope and use it as a namespace:
MyNamepace={}
MyNamespace.newvar = 'value'
// MyNamespace.newvar => 'value'
Just sharing my practice with you, I would make a global object/var in the required JavaScript file with a sensible prefix, as in if I am working on a page where this object will be a text box then I would name it:
g_TxtMyValue = 'value'; // g_ specifies it to be a global variable, it is one
// of the many conventions used
If you have more than one global variable, you can also have a namespace such as:
my_txt = {}; // For a real site I would use a prefix relative to the project
// name instead of "my".
my_txt.testValueOne = 'Value one';
my_txt.testValueOne = 'Value two';
These variables will be available to you throughout the website, after they have been initialized.
I hope this helps.
Use underscore isEmpty().
_.isEmpty('') will return true.
Just a short notice:
Is the fancybox doing AJAX (meaning: if it loads within an iFrame, you should add "parent" to the close method), like this:
parent.$.fancybox.close();