I've some reports where I use JavaScript variables between different event handlers.
Example:
//Data Set beforeOpen:
fooList = "";
//Data Set fetch:
fooList += row['foos'] + ", ";
//Dynamic Text expression, somewhere in the report:
fooList
This code works for me in 2.6.2. (There is an invisible table above this DynamicText which triggers Data Set use)
Documentation says, that I should use reportContext.setGlobalVariable("foo","bar");, but I haven't yet found, that using simple assignments is discouraged.
What are disadvantages of using simple assignments in BIRT Javascript event handlers, such as foo="bar"; and reading it later in another event handler?
By setting your variables this way you are in fact able to access them anywhere in the scripting layer. If you need to extend the reach of the variable into compiled code via a Java event handler, you would need to use the global variable to use the variable.
There is no added cost to this approach and making it a best practice ensures if you do cross any boundaries the variable's state is maintained and available for you anywhere you may need it.
Good Luck!
Related
Web App Model
Suppose I have a sensitive JS object by which I can do critical stuff. My requirement is that I would like to wrap this object entirely such that no one can access it. Here is my pattern to wrap this object.
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
By this code I export a public literal object named proxy so that every one can access it.
What is that isLegitimate? It is an abstract function to be implemented which decides which script elements access to which methods of my big apple. The decision is made with regard to src attribute of the script element. (i.e. their domain)
Others use this public API like this:
proxy.doStuffWithBigApple();
Attack Model
In my web app there are placeholders for advertising such that external contents including JavaScript codes could be loaded and get executed. All of these external resources eagerly would want to access my big apple.
Note: Those are added after my scripts resulting in there is no access to the original window.bigApple.
My Question
Is there any circumventing way for my security model?
Critical edges:
Changing src attribute at parse-time. --- Not possible, because src can only be set once.
Adding script element at run-time --- No problem is raised
Your idea of creating a proxy is good imo, however, if you have access to ES6, why not looking into Proxy? I think it does what you want out-of-the-box.
The MDN provides good examples on how do traps for value validation in a setter, etc.
EDIT :
Possible trap I have imagined :
document.currentScript is not supported in IE. So if you care about it and decide to polyfill it/use a pre-exisiting polyfill, make sure it is secure. Or it could be used to modify on the fly the external script url returned by document.currentScript and skew the proxy. I don't know if this could happen in real life tho.
This way for protecting JavaScript objects has a very significant issue which should be addressed, otherwise this way will not work properly.
MDN noted on this API that:
It's important to note that this will not reference the <script> element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
Thus, any call to proxy.doStuffWithBigApple(); inside callbacks and event handlers might lead to misbehaving of your framework.
Is there a tool for Node.js or the browser whereby I can find out which objects hold a reference to object X?
Right now I am using Backbone for front-end development and even though I remove views there still seem to be references to them afterwards.
The reason I suspect this behavior in the first place is because I am using plugin/addons for Backbone debugging in Chrome and Mozilla.
This does make me wonder if perhaps these programs themselves are the ones holding references to the Backbone objects!
First of all,Sadly there is no way to do that.
You can check who calls a function and object which specific variable holds as reference though.
It's not because of Backbone/Node.js but Javascript itself.
When you substitute object/Array, javascript only passes target memory address to the variable.
But I assume it's highly possible that the reason why you are having memory leak problem is not because of references from another variables but event handlers which is often seen in Backbone uses(also knowns as "zombie view")
Once you set events handler in a View, You need to make sure all events are unset before you actually delete the view(.remove()) unless You are using only listenTo for Backbone events and this.$el for jQuery events.
Because events set via listenTo and this.$el are automatically removed by Backbone Core when you remove a View.
And events set by Model.on or global jQuery$ would not be so.
So Please check your whole code whether You are using .on or global jQuery Object to set events, in the case You have, replace them into listenTo or this.$el.on or manually unset them Before You remove them.
I am using Adobe Flash CC to create EaselJS output manipulating the HTML5 canvas. However there seems to be a massive oversight in the ability to pass parameters to event listeners.
The issue is that I offer multiple animation outputs for compatibility, one using EaselJS and one using Raphael, however the interface that controls these remains the same, these are plain HTML elements with data stored in attributes that I wish to call functions written in the Flash IDE by triggering events and passing parameters.
I could easily find ways to avoid using EventDispatcher such as registering them with the root object and calling them directly with custom handlers. However I would rather keep my Flash IDE output as universally compatible as possible and not pollute object's namespaces I have little control over. I consider it a bad design pattern to write code in the Flash IDE that won't work without external aid.
Is there a way to pass parameters from an EaselJS event dispatcher to the listening events? I know on() provides a data parameter but that is useless as I need to pass different parameters to the same event depending upon user interaction.
You can put any properties on an Event object that you want. When you dispatch an event, you can use a string like "complete" (which is better if you don't need parameters, since it won't generate an object if there are no listeners). If you have parameters, create a new createjs.Event, and put whatever properties on it that you want:
var event = new createjs.Event("complete");
event.time = new Date();
this.dispatchEvent(event);
Then you can inspect the event object in your handler.
myObject.addEventListener("complete", handler); // add a listener
function handler(event) {
console.log(event.time);
}
Hope that helps!
I have an object, which I need to control from another object.
What's a better practice and why?
Reference the object by window.object = this in it's constructor and then call window.object.method() from the other one
or
Start listening like $(window).on 'objectEvent' and triggering the event from the other object like $(window).trigger('objectEvent')?
I am currently using the second approach, but I'm wondering, whether it's the right one.
The second approach is the least bad. You want to avoid polluting the global namespace, ie: adding properties to window.
In the second case you are adding listeners to it, which isn't that bad if you namespace event names, but the best option would be to use an intermediary object and implement the Pub/Sub pattern, so both objects interact b/w themselves through it.
Okay:
document.addEventListener('mousemove', function (e) {...code...}, false);
Recently I realized that I could greatly enhance my interaction with a few websites by way of Chrome extensions to reorder and rewrite the website to suit my needs.
So, I've been trying to get a grasp of chrome extensions, javascript, css, dom, jquery and HTML. It is a huge subject and I am woefully unfamiliar with web technologies.
Can someone please explain what 'function(e){...code...}' is in this context?
It is an inline function without a name? So, unlike other languages, instead of creating a function with a name and then calling it when needed, this statement hooks the mousemove with an unnamed function?
I suppose it is a stupid question to ask what the benefit is to having an inlined unnamed function is?
function (e) {...code...} is a reference to an anonymous function to run on the occurence of the mousemove event. The e parameter is the event Object that is sent with the event itself.
So basically you say: everytime someone moves his/her mouse around somewhere in the DOM Object document, execute the function using the event Object I give you in the parameter of that function.
You could've also used (and this is sometimes advised for readability and clarity):
function mousemover(e){ ... }
document.addEventListener('mousemove', mousemover, false);
That is also the preferred way if you later on decide to remove the eventlistener (removeEventListener).
An inline anonymous function is sometimes called a lambda function. You can read about it in this SO Question.
As per request in the comments: in javascript functions are first class objects. Specifically, this means that the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures (quoted from this wikipedia page). Also read more on Douglas Crockfords page.
They are called anonymous functions.
You can read a little more about them here:
http://en.wikipedia.org/wiki/Anonymous_function#JavaScript
Inlined (anonymous) functions are just a style thing, allowing for shorter code. They can also avoid polluting the namespace by introducing unneeded names into the current scope.
However in this particular case there is a downside in that it's impossible to remove a specific event listener if it was added anonymously.