Greasemonkey for Internet Explorer - GreasemonkIE
Lately, I've been working on a side project to bring the Greasemonkey concept of user scripts to Internet Explorer. Thus, GreasemonkIE. It's still in a very early state, and I haven't had a chance to get in all of the functionality that I'd like. However, I feel that it's far enough along that I can put out there for others to use. You can download it here. It's packaged as a Windows Installer. You'll need to restart IE after it's installed (you may need to close IE before installation). There's no gui interaction so once the progress dialog goes away, it's done.
Known issues:
- There's no nice way to install user scripts. For now, you'll have to do that by hand (see below). I'm working on adding an entry to the IE context menu for anchor tags, but that's not as clean as I'd like (only scripts can be added to IE context menus, so rather than adding an entry that calls a method in the BHO directly, I have to add an entry that calls a script that instantiates a COM class in the BHO that adds a script, and that's been causing some problems). Alternatively, I may just provide a GUI that will let you add already-downloaded scripts to GreasemonkIE.
- GreasemonkIE is written as a BHO, so you may get warnings from some anti-spyware software. If it prompts you for confirmation, allow it to install.
- Since GreasemonkIE is written in C#, you'll need to install the .NET framework if you don't already have it.
- Also because GreasemonkIE is written in C#, I haven't yet found a good way to stop explorer.exe from loading the BHO. This means that you may have problems uninstalling GreasemonkIE if you've opened any Explorer windows (iexplore.exe will release the assembly reference when it's closed, but explorer.exe will not because it doesn't close until you log out or reboot). Logging out or rebooting will allow you to uninstall GreasemonkIE.
- User scripts aren't re-applied if you refresh a web page. Internet Explorer doesn't fire the OnDocumentComplete event for page reloads, and I haven't had a chance to investigate other options.
Installing user scripts: GreasemonkIE should write an XML file under your user's application data directory ("C:\Documents and Settings\username\Application Data\GreasemonkIE\greasemonkie.xml", for example). If the folder or XML file doesn't exist, you can create them by hand. To install a new user script, add a new <script> node to greasemonkie.xml under the <scripts> node. For example, to install a user script "inline.player.user.js" that was downloaded to "C:\documents and settings\username\Application Data\GreasemonkIE\scripts\", add the following XML:
<script fileName="c:\documents and settings\username\Application Data\GreasemonkIE\scripts\inline.player.user.js" enabled="true" />GreasemonkIE will pick up any changes to the greasemonkie.xml file and load them on the next page load. Once you've installed some user scripts, you can manage them (includes, excludes, enabled, uninstall) from the "Manage User Scripts..." entry in IE's Tool menu.
I've included Dimitri Glazkov's html-xpath.js script with GreasemonkIE, which supports a good bit of the DOM Level 3 XPath implementation, but it's by no means perfect. It's also quite slow, so I'd recommend avoiding user scripts that use xpath queries. Also, due to inherent differences in the Javascript implementation between IE and FireFox, many user scripts simply will not work with GreasemonkIE. I've tested some, and here's what I've found:
Scripts that work:
- Inline MP3 Player - works flawlessly
- Linkify - painfully slow on large pages due to html-xpath.js performance issues, but it works
- Add Netflix links to IMDB - works well, but the new link has a target IE doesn't like. Shift-click the links to make them work (overrides the target)
- No Middle Man - works well
- Gmail: Adding Persistent Searches
- Google Suggest - A previous version worked using setTimeout, but this script was recently updated to use addEventListener instead, which IE's scripting model doesn't support. I ran into this on a few other scripts, and I may be able to build a work-around to support addEventListener.
- (I didn't try a whole lot of scripts, so just because this section is small doesn't mean most scripts work)
Enjoy!
Posted by Todd at March 29, 2005 9:18 PM-08:00
« XBox Live!, Linux, NAT, and UPNP | Main | GreasemonkIE update »
Comments
Nice :)
Can't install at the moment; on the mac, but will later tonight (?).
Love this wording:
"Scripts that don't use any FireFox-specific script code should work perfectly."
Some would say "standards-compliant". You say "firefox-specific". Who can really say who's right? ;-)
Posted by: Aaron at March 29, 2005 10:16 PM
Okay, "standards-compliant" :).
As far as broken scripts go, I'd rather try to build work-arounds for missing functionality in IE than force the Greasemonkey community into the depths of hell that is cross-browser javascript. I already have a few script fixes built into GreasemonkIE, and once I finish up the last bit of functionality (adding new scripts), I'll focus on automatically "fixing" scripts for GreasemonkIE so that authors don't have to.
Posted by: Todd at March 29, 2005 10:27 PM
Installed it. Could not get linkify or inline mp3 player to work. For inline mp3 player, I may not have had the correct flash version installed. For linkify, the page I tried it on was this one: http://www.mozdev.org/source/browse/greasemonkey/src/content/scripts/1102237157909?rev=1.3&content-type=text/x-cvsweb-markup
I get an XPath error from the javascript library.
But I did get the IMDB->Netflix script to work and it's quite peppy! Also, I noticed that on reload, although the script may not "run" again, the result still appears: the links to netflix are still visible. I guess IE caches the rendered result?
Patching IE will be challenging. It may pay to take a look at some of the previous attempts, most notably: http://dean.edwards.name/IE7/. Although that was on a wildly more general scale. Perhaps just dump IE7 into each page view wholesale?
In any case, cool project! Can't wait to see next iterations.
Posted by: Aaron at March 31, 2005 12:08 AM
The Xpath error doesn't surprise me. The html-xpath.js script I'm using is pretty fragile at the moment (I've done a lot of work on it already, but the performance may not make it worthwhile to continue down that path). I'll dig into the code and see if I can solve the problem for that particular page, but undoubtedly something else will come up on another page, and another.
I'm not sure why you're seeing the netflix links stick around on page refresh. That doesn't happen here, and it's a known problem that IE doesn't send useful events on refresh. Also, if you look at the page source the html is never actually changed (at least, not as far as any caching IE does is concerned), so I don't suspect that's the case. Maybe just a fluke?
I'm definitely not planning on reinventing the wheel for fixing IE. That'll take much more effort than any one person alone can give. My plan is to fix what I can, find solutions by other folks whenever possible, and cross my fingers that the real IE7 will be much more compliant (we'll see when they launch the beta, supposedly some time this summer according to various IE blogs). In the meantime, I'll look into integrating Dean's IE7 (I'm doing something similar with the html-xpath script, adding it to every page before I run any of the user scripts).
Posted by: Todd at March 31, 2005 12:21 AM
I've not touched the html-xpath in a while, and Todd's actually using it in an actual application motivated me to start hacking on it again. It doesn't seem to be our luck that the current method will provide for acceptable performance, so I am exploring the venue of a native XPath parser.
Posted by: Dimitri Glazkov at April 1, 2005 7:40 AM
(my) IE7 is mostly about patching CSS and layout bugs. There is not much JavaScript/DOM fixing going on. You may want to look at other scripts that fix-up IE's DOM. A consistent event model would be nice:
http://lojjic.net/script-library/IEtoW3C-doc.html
I'm happy to help out any way I can though. If there are bits of IE7 that you want to break out I'm happy to assist.
Posted by: Dean Edwards at April 1, 2005 12:05 PM
Hi Dimitri.
As you've said, the jscript implementation of DOM Level 3 XPath compliance does have some performance issues, and I don't know if it will be possible to work through those. I've been following the approach of, "Make it work, make it work right, make it work fast," so I have no problems including html-xpath.js for now. I'm still mostly in the "make it work" phase. Even if GreasemonkIE does need to eventually drop html-xpath.js in favor of a faster implementation (perhaps IE7 will have native support?), I've already contributed a good number of fixes back to Dimitri that will help html-xpath.js independently of GreasemonkIE.
It's good to hear you're actively working on html-xpath.js again.
Posted by: Todd at April 1, 2005 12:58 PM
I've been thinking about this a little more.
Patching IE is too slow. Especially the event model. On a Mozilla platform you have access to the underlying DOM objects. It is an easy matter to extend the interfaces of any object you like. To do the same on IE, you have to extend the interface of each individual DOM object. This is really really slow.
User scripts are no different to other scripts IMO. I think you should keep GreaseMonkIE simple. The same as the original GreaseMonkey. Keep it as a mechanism for injecting user scripts.
One possiblity is that you guys (Todd and Aaron) could come up with a mini API to aid in the creation of cross-browser user scripts. GM_addEventListener immediately springs to mind. :-)
My real belief is that both GMs should be plain and simple. Leave the cross-browser headache to the scripters themselves.
Posted by: Dean Edwards at April 3, 2005 3:07 AM
Dean,
What you say makes sense, and given other technical hurdles GreasemonkIE still needs to get over (chief among which is re-applying scripts on page reload) it could be some time before I can focus solely on compatibility issue. However, one of my goals here was not to splinter the user scripting community. There's enough animosity towards IE out there already. I really don't want to be responsible for more of it. ("That damned Todd, he had to go and splinter the Greasemonkey community.") Because GMIE is following in the footsteps of GM, I'm very conscious about not screwing up what Aaron has built.
My thoughts on this have lately turned towards exposing compatibility hacks as options (perhaps even as a completely separate project from GMIE core). That way, the end user can make the determination between "slow and compatible" or "fast and incompatible". That would work well so long as GMIE stays a niche tool. If it takes off, most users will just use whatever the default setting is (which would probably be "fast and incompatible"), and then I'd get a lot of bug reports about non-working scripts.
Throwing in the towel and acknowledging that IE's standards support sucks seems like quitting prematurely. Then again, you have much more experience in the pains of IE than I do (I'm not a DHTML developer like Aaron, or a CSS guru, or anything like that -- I'm a .NET and SQL developer who happened upon the thought that IE could do user scripts, too).
Maybe (the real) IE7 will come to save the day? Here's hoping ...
Posted by: Todd at April 3, 2005 1:17 PM
Posted by: Dean Edwards at April 4, 2005 9:20 AM
Good stuff! You should be able to hook the onload event of the HTMLDocumentEvents interface from MSHTML to know when the document has either been refreshed or navigated forward/back to.
HTH,
Drew
Posted by: Drew Marsh at April 11, 2005 5:13 PM
Like it. Good luck ironing out the glitches, I'll be taking great interest in this.
Posted by: Jon at April 18, 2005 2:21 AM
But what about Turnabout?
http://www.reifysoft.com/turnabout.php
Posted by: Vilky F. at August 6, 2005 11:55 AM
You should definitely check out:
http://sourceforge.net/projects/goog-ajaxslt/
It's Google's take at providing non-native XSLT support in legacy browsers, and it comes w/ an XPath layer for MSIE, too.
Posted by: Niko Klaric at November 29, 2005 12:14 AM