originally posted in:BungieNetPlatform
View Entire Topic
Bungie.net's update to Bungie.next means scripting pages is a little... different. On most other sites, and in the New Hawtness, the entire page source was sent straight from the server and function bindings were created then and there while simultaneously rendering elements on the page. Bungie.next on the other hand is very much a client-side web application, which consumes data from different web services, combines it with HTML within Javascript, then puts it on the page. That process makes it a little more difficult with scripting.
Previously you could write a script with a document.getElementById to grab an element right at the top of your userscript because the element actually existed in the DOM at the time of execution. Now, because elements are created on the fly, you'll end up with race conditions where your userscript is executing immediately to try to get an element which hasn't been created yet. What you [i]should[/i] do in this case is write scripts which react to a particular event which lets you know when it's appropriate to execute your code.
But what events would those be? You [i]could[/i] take a literal approach and bind an event handler to a DOM object. Say, the window or document, and listen for Load, Ready, DomContentLoaded, etc... and this may work for you depending on what you're trying to achieve, but these types of events are limited, because they can't provide you any application-level event handling; there's no OnNewTopic, OnPost, or OnForumRendered events for your user code. So we will define these ourselves.
The advantage we have here is that Bungie.net's content scripts and our userscripts can access the same global scope, so we can easily make use of content script variables... but we can also modify them. Consider the following:
[quote]//bnet content script
function A(){ }[/quote]
[quote]//userscript
function B(){ }[/quote]
Now let's say that function A is used by another bungie.net script as a click handler for a button, and we want to know in our userscript when this occurs and execute function B as well.
[quote]//userscript
function B(){ }
var oldF = A;
var newF = function(){
B();
oldF.apply(this, arguments);
}
A = newF;[/quote]There's a bit going on here.
1. We declare a new variable and store a reference to [i]the function[/i] also referred to by A.
2. We declare a new function named newF (more on this in a moment).
3. We assign a reference to the new function we just created, newF, in variable A.
So now when A is called, because it's pointing to newF, it will execute that instead. Within the newF function we do a couple of things.
1. We execute our own function, B.
2. We then execute the originally bound function, referred to using oldF, but do so using the apply method, which modifies the context of the function being called. In this case we're passing the this pointer from whichever object called newF through A to the original function, oldF, and also passing its arguments. The original function will execute as if it had been called without our intercepting code.
As you can see here, using the newF function to intercept function calls can give us a way of creating events before and after the call to the original function. To see how I've implemented this, as well as some [i]really[/i] hacky stuff getting jQuery events, have a look at the [url=http://www.bungie.net/en-us/Groups/Post?id=60304745&groupId=39966]BNextEventServer script[/url].
-
Does anyone remember the guy who made a script but took it down because he didn't have a lot of followers?