My question basically refers to this example:
https://github.com/vlandham/vlandham.github.com/blob/master/vis/gates/coffee/vis.coffee
At the end of this script (on line 202) it calls the (view_type) parameter from the front end and based on the view type ('year' or 'all') renders the exact method. I need to implement the a similar strategy, but within the show_details() method of this script (on line 176)..What I precisely need is to retrieve the view_type in the show_details() method and based on the view type ('year' or 'all') decide what the content variable (in show_details() method) should display..any ideas or help will be really helpful. Thank you.
So cofeescript automatically inserts local var statements for any variable referenced inside a function (precisely to prevent global leakage that JavaScript causes by default). This means you have to explicitly pollute some global namespace which in a browser would be the window object. Nothing in CofeeScript will prevent you from assigning a field of your choice with what ever value you need and reading it back any time you need. Note that this is messy and prevented for a reason (its hard to keep this kind of code clean, also there is no window object in a server side envrionment like node.js), but it will work.
Related
I would like to be able to expose a function-scoped variable that is part of a website's (not mine) javascript.
Here's a simplified example:
function addHooks(e, t, n, i) {
var props = { // Would like to expose this
update: function() { ... },
remove: function() { ... },
find: function() { ... },
};
...
}
In the above example, I would like to expose the props variable so that my webextension can then access this to modify the behavior of the website. Please note, that the website that serves this JS file isn't under my control and thus, I cannot simply modify the source file to export this variable. However, I'm fully open to modifying the final code that the browser runs (I just don't know how to). The javascript file containing the addHooks function appears to be added dynamically via XHR.
Although I have no idea on how to accomplish this programmatically, I have had some success setting a breakpoint and then issuing window.siteController = props in the browser's developer console. Unfortunately, manual user-intervention is not something I can package and distribute.
One method that I have been toying with is the idea of making an AJAX request for the JS file, modifying its script contents and appending it to the page.
Is there a canonical, programmatic way in which a function-scoped variable can be exposed?
if it's the props object variable that you want exposed, you could return he entire object from the functin, like in closures.
Or , you could, simple declare a the enclosing function as a constructor function, set props as this.props and then, invoke the same function elsewhere, using the new keyword.
Let me know if this helps
EDIT:
Thanks to Makyen who pointed out my error.
Apparently you might be able to do it if you re-define the function in a page script and insert it as a script element. (See the comment for two references).
Just be sure that your <script> element is inserted after the original definition and then you can either return props at the end of the function, or use this.props and use the function either as a constructor or using thecallfunction, passing an object that will get the props property added.
Old answer ( __ wrong__ apparently)
Short answer: you can't.
Full explanation: if you can't change the code of the function and you can only use the function (call it) you cannot alter its variable's scope (and good thing you can't, too. There's a reason why the variable was limited to its current scope).
And you can't change the website's JavaScript. As a Firefox or Chrome extension (and possibly the same fires to other browsers I'm not sure) you can't even access the function (let alone it's inner variables). I mean to say you can't even call it from the extension of it's in the website's code.
content scripts cannot see JavaScript variables defined by page scripts
More info and source
Firefox/Chrome runs your JavaScript code in a parallel environment, isolated from the website's environment. This is of course for security reasons. It also helps for you to be able to develop without knowing the exact inner workings of each website your code might be injected into, as you don't need to bother regarding naming conflicts (which would be impossible if it weren't for the separation environments).
The only thing you do have access to is the DOM, through which you can gather information, alter the website and even talk with the website in some cases (the website should follow a protocol you decide upon as well).
I realised that I don't know how variables are injected into JavaScript in HTML.
I would like to test overriding a clickTag variable which is simply a var in the main body of a JavaScript ( a default value ), but to override it with the injected variable.
Something like this >
somewhere.com/index.html?{"clickTag":"http://www.something.com"}
What's the best way to do that ?
Pretty basic, but I've been used to having the DoubleClick Enabler handling that for me and I have not thought about how the data actually gets in, and how I could test it.
( for a basic php file, passing variables the simplest way, it would be work.php?play=good&balance=true etc but I'm not finding a question here for what I have asked )
Please also correct my terminology if it is bad or misleading. Thanks.
Variables aren't injected into JavaScript.
A JavaScript program defines variables. It might get values to assign to them by accessing APIs (such as location in a web browser which would give you details of the URL of the page).
If you want to override the value of a variable in an existing program then you would need to change the source code of that program to write a new value to that variable between the point where it would normally be assigned and the point where it gets read back and used.
I am developing a JS game and wish to prevent cheating as much as possible. I understand that this is near impossible but I would like to prevent users from going into the console and changing their lives by saying something like game.lives = 99;
Is there a way I can detect if a variable such as lives has been changed from the console thus marking the game hacked and stopping the execution of my code? I understand I could do server side checking but I want to avoid lag. I am looking for a JS answer if there is one.
You won't be able to completely stop a user from changing the javascript code or variable values. You only can make it more difficult. Fisch mentioned using closure so as all variables will be private. Look into the immediately invoked function expression (IIFE) pattern. It's used in a lot of plugin style code and helps prevent modifications.
If a user wants to change a variables value, nothing will stop them from running the game in debug mode and modifying values at breakpoints.
You could use a closure which would essentially make all your variables private and thus not accessible from the console. If you need to have some public variables and methods, you could use a revealing module pattern. you can read more about them here: http://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/
I have a ajax form that populates select lists with values based on the previous selected select list item. This form is used in 3 different views with each view adding an extra select list. I have written some basic validation code that keeps the form process in sync and doesn't confuse the user.
I have written one function that handles all 3 forms in an external script file.
My Question:
Is it acceptable or is there anything I need to worry about if some of my variables are undefined based on the form and view?
Here is some sample code that illustrates my question:
Note: These are not the actual names of my variables.
(function ($){
var objects = {sl1:$('#SelectList1'),sl2:$('#SelectList2'),sl3:$('#SelectList3'),lbl1:$('#Label1'),lbl2:$('#Label2'),lbl3:$('#Label3')};
objects.sl1.change(function(){
mapValues();
}
function mapValues(){
objects.lbl1.text(objects.sl1.val());
objects.lbl2.text(objects.sl2.val());
objects.lbl3.text(objects.sl3.val());//What if this select list is undefined for View1?
}
})(jQuery);
To summarize, View #1 has SelectList1 & SelectList2. View #2 has all 3. Is there a performance issue or is it bad practice to call a function where some of the variables are undefined?
Thanks.
This is more of a jQuery issue, not a JS one. jQuery simply does nothing (it does not even fail!) if you execute a method such as .text() or .val() on an empty result from a selector. For the performance issue, test it yourself. If the element is not found, I expect the performance to be a little better compared to when an element exists.
So, it's valid to use such code.
Note that you're mixing up "undefined variables" with "non-available elements" which are totally different matters. Using undefined variables is strongly discouraged and often lead to unexpected behavior.
I think it's more about readability and maintainability at this point. I mean would it be clear to another developer just by looking at your JS that View #1 has SelectList1 & SelectList2 ? Looking at the code you would think it has all three since all the forms use the same JS. Maybe making it more flexible to where individual forms can specify which selectLists are contained within the respective form, this way the global script is only using the selectLists specified in the forms and not assuming all at available.
Yes it is bad practice. And is source of bugs.
For good practice, define default value, and/or check for it in your function.
thats why you should use the || operator
e.g. :
( $('#SelectList1').length || '0')
The issue is that you will introduce a level of uncertainty, and hence hard to trace bugs, if you do so. Different JS parsers will respond differently - some are more forgiving and will do nothing, others will just crash. So right away you have potential cross-browser issues.
Further, as those variables get passed around inside your code, if you do not know their values, you'll have a difficult time predicting how the rest of your code will interact with them. So now you also have potential logic/program bugs.
So do yourself a favor and a) check that any required parameters are passed, and do some error handling if it is not and b) make sure optional parameters are handled as soon as you receive them (eg assign them a default value, make sure they don't get passed on to other functions if they are not defined, whatever is most appropriate for your application logic).
My JavaScript is pretty nominal, so when I saw this construction, I was kind of baffled:
var shareProxiesPref = document.getElementById("network.proxy.share_proxy_settings");
shareProxiesPref.disabled = proxyTypePref.value != 1;
Isn't it better to do an if on proxyTypePref.value, and then declare the var inside the result, only if you need it?
(Incidentally, I also found this form very hard to read in comparison to the normal usage. There were a set of two or three of these conditionals, instead of doing a single if with a block of statements in the result.)
UPDATE:
The responses were very helpful and asked for more context. The code fragment is from Firefox 3, so you can see the code here:
http://mxr.mozilla.org/firefox/source/browser/components/preferences/connection.js
Basically, when you look at the Connect preferences window in Firefox, clicking the proxy modes (radio buttons), causes various form elements to enable|disable.
It depends on the context of this code. If it's running on page load, then it would be better to put this code in an if block.
But, if this is part of a validation function, and the field switches between enabled and disabled throughout the life of the page, then this code sort of makes sense.
It's important to remember that setting disabled to false also alters page state.
(Incidentally, I also found this form very hard to read in comparison to the normal usage.
Not necessarily, although that was my first thought, too. A code should always emphasize its function, especially if it has side effects. If the writer's intention was to emphasize the assignment to sharedProxiesPref.disabled then hey, roll with it. On the other hand, it could have been clearer that the action taking place here is to disable the object, in which case the conditional block would have been better.
It's hard to say what's better to do without more context.
If this code being executed every time that proxyTypePref changes, then you're always going to need set shareProxiesPref.disabled.
I would agree than an if statement would be a bit more readable than the current code.
Isn't it better to do an if on proxyTypePref.value, and then declare the var inside the result, only if you need it?
If you're talking strictly about variable declaration, then it doesn't matter whether or not you put it inside an if statement. Any Javascript variable declared inside a function is in scope for the entire function, regardless of where it is declared.
If you're talking about the execution of document.getElementById, then yes, it is much better to not make that call if you don't have to.