| Forum Home | ||||
| Press F1 | ||||
| Thread ID: 119060 | 2011-07-02 12:42:00 | Javascript help - What's meant by wrap your "loose" variables and functions? | Renmoo (66) | Press F1 |
| Post ID | Timestamp | Content | User | ||
| 1214239 | 2011-07-02 12:42:00 | Hiya all, A Firefox Add-on that I created a year ago had been reviewed by one of the editors, in which he commented that 1) In order to prevent conflicts with other add-ons that may be installed by users, you need to wrap your "loose" variables and functions within a JavaScript object. You can see examples on how to do this at developer.mozilla.org The piece of javascript code that I had created is as below: function hello() { var l=content.document.location,h=l.host; gBrowser.loadURI(l.href.replace(h,h+'.ezproxy.auck land.ac.nz')); } What do I need to do to wrap up the variables and functions? I took a look at the document provided, but I still haven't got a clue what's going on. Thanks :) [Edit] The title should've read "What's meant by wrapping your loose variables and functions?" |
Renmoo (66) | ||
| 1214240 | 2011-07-02 12:46:00 | Here's an example forums.mozillazine.org The guy had window.addEventListener("load", pcache.pcacheinit(), false); It should have been window.addEventListener("load", pcache.pcacheinit, false); |
Speedy Gonzales (78) | ||
| 1214241 | 2011-07-02 13:18:00 | But..... What does it mean? And what do I have to do to my code as a result? | Renmoo (66) | ||
| 1214242 | 2011-07-02 13:25:00 | Pass change it somewhere I suppose. I know nothing about Java. Do a search in Google on what that guy said. It would have helped if he / she told you what the prob was. And how to fix it | Speedy Gonzales (78) | ||
| 1214243 | 2011-07-03 03:46:00 | Here's an example forums.mozillazine.org The guy had window.addEventListener("load", pcache.pcacheinit(), false); It should have been window.addEventListener("load", pcache.pcacheinit, false);Speedy, that's completely irrelevant; the problem fixed in your example is *not* the problem the OP needed solved, and has nothing to do with wrapping functions / variables (what your example actually shows is a common mistake in using callback functions). If you're going to provide examples, please make sure they actually illustrate the issue at hand rather than something completely different. The thread you linked to contained more than one problem. Pass change it somewhere I suppose.That much is obvious :p. I know nothing about Java.Java is *not* the same thing as JavaScript - they're completely different languages, and are not related in any way. JavaScript is also known as ECMAScript. Also, if you know nothing about the topic at hand, why are you providing advice without first mentioning that caveat? Do a search in Google on what that guy said.That's not helpful; I suspect the reason that the OP is asking for help is because they don't understand what they are being asked to do, and don't know enough about it to understand what's relevant. It would have helped if he / she told you what the prob was. And how to fix itHe / she did - they said exactly what the problem was and how to fix it, but apparently assumed they were dealing with someone who had a better understanding of JavaScript than the OP actually has. Renmoo: What the reviewer is saying is that you should avoid declaring functions or variables in the global scope, as they can conflict with those declared by other extensions. In your case, the 'hello' function is the one at fault here. What you need to do is declare a new object that encapsulates your entire extension, and then declare your functions as members. This means that your functions are local to the object's internal scope, rather than global. A great example of this can be found in the documentation that the reviewer linked you to. As you seem to be having trouble understanding it, I've added a bunch of comments - please let me know if you need more detail, or if you don't fully understand the explanation. 01 /** 02 * XULSchoolChrome namespace. 03 */ 04 if ("undefined" == typeof(XULSchoolChrome)) { //Check to see if the XULSchoolChrome variable //has already been defined; if it has, we don't //need to do anything else. 05 var XULSchoolChrome = { //Declare the variable as an object - the object //is everything inside this set of braces {}. 06 /** 07 * Initializes this object. 08 */ 09 init : function() { //Declare the 'init' function as a member / property //of the object (name: value syntax, value is an //anonymous function). 10 this.obsService = //Internal body of the 'init' function 11 Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); 12 } //End of the 'init' function - if you wanted to //declare more functions, you'd put a comma after //the closing brace of each function. 13 }; //The brace closes the object definition, and the //semicolon ends the assignment statement - the //XULChromeSchool variable now contains the object //defined above. 14 15 /** 16 * Constructor. 17 */ 18 (function() { //Another anonymous function - this one runs the //'init' function, and is effectively used as a //class constructor. 19 this.init(); 20 }).apply(XULSchoolChrome); 21 }; //End of the outer 'if' statement. |
Erayd (23) | ||
| 1214244 | 2011-07-03 04:45:00 | Renmoo: What the reviewer is saying is that you should avoid declaring functions or variables in the global scope, as they can conflict with those declared by other extensions . In your case, the 'hello' function is the one at fault here . Understood . What you need to do is declare a new object that encapsulates your entire extension, and then declare your functions as members . This means that your functions are local to the object's internal scope, rather than global . I see . In other words, the function that the extension calls for should apply only within the object's scope . A great example of this can be found in the documentation that the reviewer linked you to This is the point that I get confused . On the one hand, the editor was talking about wrapping up loose functions and variables within a JS file, but on the other hand, the document that was linked mentions the following: The first step to good JavaScript object management is having a namespace that you know will not conflict with Firefox code or other extensions . Namespace declaration is best located in a file of its own, so that you have this one JS file that should be included in all of your XUL files . Does this mean I need to alter my . xul files as well? The code for my . xul file goes as follows: <overlay id="journaluoaOverlay" xmlns=" . mozilla . org/keymaster/gatekeeper/there . is . only . xul">" target="_blank">www . mozilla . org // This imports our javascript . <script type="application/x-javascript" src="chrome://journaluoa/content/journaluoaOverlay . js"> </script> // Statusbar <statusbar id="status-bar"> <statusbarpanel id="trigger" label="JournalUoA" tooltiptext="Access the full version" onmousedown="hello();" /> </statusbar> </overlay> As you seem to be having trouble understanding it, I've added a bunch of comments - please let me know if you need more detail, or if you don't fully understand the explanation . 01 /** 02 * XULSchoolChrome namespace . 03 */ 04 if ("undefined" == typeof(XULSchoolChrome)) { //Check to see if the XULSchoolChrome variable //has already been defined; if it has, we don't //need to do anything else . 05 var XULSchoolChrome = { //Declare the variable as an object - the object //is everything inside this set of braces {} . 06 /** 07 * Initializes this object . 08 */ 09 init : function() { //Declare the 'init' function as a member / property //of the object (name: value syntax, value is an //anonymous function) . 10 this . obsService = //Internal body of the 'init' function 11 Cc["@mozilla . org/observer-service;1"] . getService(Ci . nsIObserverService); 12 } //End of the 'init' function - if you wanted to //declare more functions, you'd put a comma after //the closing brace of each function . 13 }; //The brace closes the object definition, and the //semicolon ends the assignment statement - the //XULChromeSchool variable now contains the object //defined above . 14 15 /** 16 * Constructor . 17 */ 18 (function() { //Another anonymous function - this one runs the //'init' function, and is effectively used as a //class constructor . 19 this . init(); 20 }) . apply(XULSchoolChrome); 21 }; //End of the outer 'if' statement . Thanks for the detailed explanation, Erayd . I roughly understand the concepts the document is trying to describe . What I don't get it is how to apply the understanding to my situation . My current javascript code is: function hello() { var l=content . document . location,h=l . host; gBrowser . loadURI(l . href . replace(h,h+' . ezproxy . auck land . ac . nz')); } I guess firstly I need to use the following lines to check if the variable "l" has already been taken up by other add-ons: 1 /** 2 * XULSchoolChrome namespace . 3 */ 4 if ("undefined" == typeof(XULSchoolChrome)) { 5 var XULSchoolChrome = {}; 6 }; I am not sure how to progress from here . Sorry to be a pain in the butt :o Thanks :) |
Renmoo (66) | ||
| 1214245 | 2011-07-03 04:57:00 | In other words, the function that the extension calls for should apply only within the object's scope . Correct . This is the point that I get confused . On the one hand, the editor was talking about wrapping up loose functions and variables within a JS file, but on the other hand, the document that was linked mentions the following: The first step to good JavaScript object management is having a namespace that you know will not conflict with Firefox code or other extensions . Namespace declaration is best located in a file of its own, so that you have this one JS file that should be included in all of your XUL files . I think I see where you're getting confused . Simply putting things in a different file doesn't automatically declare a namespace - that's what the wrapper object is for - and all files share the same global scope . JavaScript doesn't natively have any concept of namespaces, but objects can do the same job reasonably well . What that bit of documentation you quoted means is that you should put your wrapper object definition in a separate file . Does this mean I need to alter my . xul files as well? The code for my . xul file goes as follows: <overlay id="journaluoaOverlay" xmlns=" . mozilla . org/keymaster/gatekeeper/there . is . only . xul">" target="_blank">www . mozilla . org // This imports our javascript . <script type="application/x-javascript" src="chrome://journaluoa/content/journaluoaOverlay . js"> </script> // Statusbar <statusbar id="status-bar"> <statusbarpanel id="trigger" label="JournalUoA" tooltiptext="Access the full version" onmousedown="hello();" /> </statusbar> </overlay>Yes - you need to change the function call in the onmousedown attribute . Thanks for the detailed explanation, Erayd . You're most welcome :) . I roughly understand the concepts the document is trying to describe . What I don't get it is how to apply the understanding to my situation . Where are you getting stuck? I guess firstly I need to use the following lines to check if the variable "l" has already been taken up by other add-ons: 1 /** 2 * XULSchoolChrome namespace . 3 */ 4 if ("undefined" == typeof(XULSchoolChrome)) { 5 var XULSchoolChrome = {}; 6 }; Yep - pick some unique variable name for your extension, and ensure it's free . If it is free, then define it inside the 'if' block . I am not sure how to progress from here . If you let me know which bit is confusing you, or which concept you're not quite getting, I'll see if I can explain it in a different way that might be a bit clearer . I'm not sure how much programming experience you have, so please let me know if I'm using terms you're not familiar with . |
Erayd (23) | ||
| 1214246 | 2011-07-03 05:19:00 | I think I see where you're getting confused. Simply putting things in a different file doesn't automatically declare a namespace - that's what the wrapper object is for - and all files share the same global scope. JavaScript doesn't natively have any concept of namespaces, but objects can do the same job reasonably well. What that bit of documentation you quoted means is that you should put your wrapper object definition in a separate file. :dogeye: What is a wrapper object definition? Yes - you need to change the function call in the onmousedown attribute. Okay, got it. Let me try and get the JS file right first: Previous code: function hello() { var l=content.document.location,h=l.host; gBrowser.loadURI(l.href.replace(h,h+'.ezproxy.auck land.ac.nz')); } New code: /** * XULSchoolChrome namespace. */ if {"undefined" == typeof{ezproxyswitchover}} { var ezproxyswitchover = { init : function () { var obtainaddress = content.document.location, newaddress=obtainaddress.host; gBrowser.loadURI(obtainaddress.href.replace(newadd ress,newaddress+'.ezproxy.auckland.ac.nz')); } } /** * Constructor. */ (function() { this.init(); } ).apply(ezproxyswitchover); }; I understand namespace is what you use to identify a group of functions so that they are localised to a particular extension. Do I need to insert anything special in the first three lines? Based on the explanation that you provided earlier, I have kind of adapted the code to my javascript file. How do I call for the execution of ezproxyswitchover function in the xul file? If you let me know which bit is confusing you, or which concept you're not quite getting, I'll see if I can explain it in a different way that might be a bit clearer. I'm not sure how much programming experience you have, so please let me know if I'm using terms you're not familiar with I am only familiar with HTML and CSS, that's all :p. |
Renmoo (66) | ||
| 1214247 | 2011-07-03 06:20:00 | :dogeye: What is a wrapper object definition?It's the bit where you define the wrapper object - i . e . where you create an object that contains your functions etc and assign it to a variable (see line 5 of the example) . Okay, got it . Let me try and get the JS file right first: Previous code: function hello() { var l=content . document . location,h=l . host; gBrowser . loadURI(l . href . replace(h,h+' . ezproxy . auck land . ac . nz')); } New code: /** * XULSchoolChrome namespace . */ if {"undefined" == typeof{ezproxyswitchover}} { var ezproxyswitchover = { init : function () { var obtainaddress = content . document . location, newaddress=obtainaddress . host; gBrowser . loadURI(obtainaddress . href . replace(newadd ress,newaddress+' . ezproxy . auckland . ac . nz')); } } /** * Constructor . */ (function() { this . init(); } ) . apply(ezproxyswitchover); };I don't think you need the constructor at all in this case, as you're not needing to do anything immediately when the JS file is included . Otherwise this looks fine . I understand namespace is what you use to identify a group of functions so that they are localised to a particular extension . Almost, but not quite . A namespace is effectively a named global scope, and is used to avoid conflicts between global entities . JavaScript doesn't have namespaces, but it does have very flexible objects that can be used to achieve the same thing . Generally you'd want your extension to have a unique namespace, but if you were developing several extensions that shared functionality, you may wish to use a single namespace across all of them . Do I need to insert anything special in the first three lines? No - the first three lines are a comment . Based on the explanation that you provided earlier, I have kind of adapted the code to my javascript file . How do I call for the execution of ezproxyswitchover function in the xul file?Assuming you don't change the code you've just posted, hello() would be replaced with ezproxyswitchover . init() . I am only familiar with HTML and CSS, that's all :p . OK - in that case, please let me know if I use any terminology or concepts you're unfamiliar with; HTML and CSS are formatting languages, not programming languages . |
Erayd (23) | ||
| 1 | |||||