So I went to add this splitview thing to my Greasemonkey script for Hacker News, only I did the same thing without hitting your site for the frameset (completely clientside js). It works quite nicely, but for some reason I had to resort to something I consider quite ugly.
Can someone please look at the code below (and read my comments in it) and tell me why the three addEventListeners that I have commented out won't work? I'd really really like to know why I am being retarded and how to fix it, as the solution I ended up with seems unnecessarily ugly.
Disclaimer: I've never used Greasemonkey (now an Opera user) and have only spent a few minutes trying to figure out how it interfaces with the browser. I know my way around JS though.
That said, after doing some testing I think your issue is that the page isn't completely loaded before the addEventListener is called. Changing the addEventListener line to a simple element.onclick = function(alert) triggers an error in the browser; so does trying to ask about the element's onclick function. Putting in an alert box in place of the addEventListener line pretty clearly demonstrates that the page is still loading when the code is being called on the links. Firefox is a little touchy about that.
I'm still working on it, lemme see what happens if I wrap up your script's initialization section into a document.onload, or something similar.
Edit: Also, elements are being returned as XPCNativeWrapper objects [http://developer.mozilla.org/en/docs/XPCNativeWrapper]. I'm totally unfamiliar with those; maybe that's interfering with the event attachment somehow?
Edit: Yeah, looks like it. I wasn't sure, so I had to test, but references to elements from directly inside the code body get the XPCNativeWrapper objects, which provide protection for some properties. But, code called from a setTimeout doesn't get those objects, and gets direct access to the elements. Not sure how to fix that right since I've never encountered that before.
Yeah I learned about the XPCNativeWrapper objects last night too. Basically GM has access to every object (from window/document on down) as one of these for security purposes (so the target page can't redefine standard methods). Due to the vagaries of the way they are implemented, you can't call the onclick/onkeypress/etc methods directly. It actually states in the documentation that addEventListener is the preferred (and only working) method.
You can supposedly get access to the underlying JS object from the XPCNativeWrapper object with the wrappedJSObject property and then act on it, but it's a big security no-no. I tried it anyway to no avail.
Your thought on the page not being loaded is kind of where I ended up too. However, my understanding was that GM ran user scripts after the window.onload finished, but I could be completely wrong here. If I assign all the links id attributes in the GM script and then manually add event listeners in my Firebug console, they work fine. Also, you'll notice that later in my script I add click listeners on other items (buttons and links) that work swimmingly, so it's either entirely arbitrary or I'm missing something very obvious.
Thanks for looking at this, I'll look forward to any other thoughts you have.
EDIT: Looks like I was very wrong about the GM script executing after the window load event. I have been playing with wrapping code in a load event listener and have indeed got it working that way. Thanks for the suggestion! I'll hopefully have something polished and posted soon.
Yay! Glad you got it sorted out. I was stumped, and finally ran out of time to keep tinkering with it. Even with the code firing after the page was done loading, I still couldn't get it working right.
| You can supposedly get access to the underlying JS object from the XPCNativeWrapper object with the wrappedJSObject property and then act on it, but it's a big security no-no. I tried it anyway to no avail.
The other wrong way that I found out about was the unsafeWindow object; same kind of deal, gives you direct access to the page.
I've installed the script under Safari and FF2 and I don't notice anything happening. Is it overwriting the existing links? I didn't do that because sometimes I may only want to quickly see the comments or main article.
Firebug doesn't seem to be showing me any errors either.
BTW: I like the title of your blog, "Artfully Underemployed" :)
If you installed it for the first time, make sure you turn the feature on. Look for the link called "blacklist" in the top bar of HN, which will pull up the options for the script. Check the box next to split view.
Since this is becoming more than just the simple blacklist script it originally was, I suppose I should rename it or something to make that more clear. ;)
Oh and I almost forgot, thanks for the brilliant idea!
Cool, I got it to work in FF. It doesn't work under Safari (no blacklist in the toolbar). I noticed extra scroll bars in FF but my guess is that's because there is some css padding/margin stuff applied to the body.
Because it overrides the page itself you can't click "Back" or Alt+Left or whatever to go back to the list of stories.
I did go back and add the check for if I'm already inside the frameset to my code though. Gotta prevent those recursive split views :). Now if you surf back to the main page in the right frame and click on a SplitView link it will reload both frames.
I will look at it in Safari some and see if I can figure out what the deal is there. Safari's Activity window doesn't show any errors.
I'll also see what I can think of for the Back button issue when doing it your way. That may not be a big deal to anyone else though.
I'll keep the back button thing in mind when I look at it again... and I noticed the weird scrollbar stuff too. I'll have to fix that at some point. I've been up since 4pm yesterday, and seeing as how it is noon, think I'm going to head towards bed for a bit.
I didnt look to closely, but it looks like you are creating a closure around the comments var for your event listener function. The problem is that you are doing this within a loop, meaning the comments var changes after each iteraion, probably ending up in something you hadnt intended
Can someone please look at the code below (and read my comments in it) and tell me why the three addEventListeners that I have commented out won't work? I'd really really like to know why I am being retarded and how to fix it, as the solution I ended up with seems unnecessarily ugly.
View code here: http://userscripts.org/scripts/review/25039
Or if you don't care about it being ugly and just want to use it: http://userscripts.org/scripts/show/25039
But I'd really appreciate help with figuring out the issue with the addEventListeners.