Archive for March, 2009

I finally got around to implementing a decent Syntax highlighter for code on my site. I looked at a number of different projects, and none of them had exactly all the features I wanted, so I went with WP-Syntax by Ryan McGeary available here: http://ryan.mcgeary.org/wp-syntax/ which in turn is based on GeSHi (Generic Syntax Highlighter) available here: http://qbnz.com/highlighter/

I liked how Ryan handled the line numbering on the left, but it was missing a nice way to quickly view the code in plain text, copy the code to your clipboard, or save it directly as a download. Several of the other solutions had features like that in the top header of the code, and I liked that, so I quickly hacked in support for that. The show in plain text icon simply leverages the built in thickbox.js built into WordPress and some JavaScript to get that done I quickly shoehorned that in. The other two icons for copy to clipboard and download and save were done through Flash. I leveraged the System.setClipboard() function to quickly push the code onto the users clipboard, as well as externalInterface to pass back a success notification to the browser and end user.

For the file download and save code, I was going to use AS3 and the filereference.download feature, and javascript to parse the code out of the page, and then download it directly to the users system with a standard OS dialog – but it was late and I didn’t feel like spending the time to parse the innerHTML with JS before passing it in to Flash – so I cheated and just pass it all in as a urlencoded Flashvar, and then do a roundtrip to my server with the code as POST data, and then leverage the filereference.download feature of Flash 8 AS 2.0 to accomplish what looks like the identical¬†behavior. I’ll probably go back and clean this up and redo it the right way with AS3 so I don’t have to make that server trip, but I’ll save that for another day. The current version is smart enough to know when ActionScript is the language and automatically set the default filename extension to .as – and it also broadcasts a little download complete to the browser via externalInterface when things are complete, so its 99% of what I wanted and also nearly 100% compatible with most users installs of Flash. The tiny nature of the size of the SWF doesn’t lend itself to even using the Express Install feature of Flash 6+ to upgrade to 9, so think this was a good compromise, although I already have a workaround for that as well, with a self-resizing DIV and SWF combo.

I would also like to clean things up a bit more including making some more XHTML friendly changes to the html output and then submit my changes to Ryan for inclusion in a future version, as it would probably be too much ongoing work to make and then maintain a plugin that patches his plugin. Anyway, below is a quick sample of the output with a handy little contrain/resizing function I use often. Including some basic CSS adjustments to give alternating background colors on the lines (it looks decent in Safari at default text settings, but I have to put in some conditional CSS tweaks for other browsers to get the alternating line colors to line up better) – at least I now have a solution I like for posting code snippets. If anyone wants to get the source for this and hack away at it yourself, let me know and maybe I’ll bundle things up as they stand now and someone else can refine things a bit further, its really only some changes to the main wp-synax.php file, a dependency on SWFObject 2.1, and the custom little Flash widget I put together.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// AS3 example function to constrain an object's width/height proportionally with a given objects new targeted dimensions with optional rounding
function reSize (originalSize:Object, targetConstraints:Object, round:Boolean):Object {
    var scaleFactor:Number = Math.min( (targetConstraints.width / originalSize.width), (targetConstraints.height / originalSize.height) );
    var newSize:Object = new Object  ;
    newSize.width = round ? Math.round(scaleFactor * originalSize.width) : (scaleFactor * originalSize.width);
    newSize.height = round ? Math.round(scaleFactor * originalSize.height) : (scaleFactor * originalSize.height);
    return newSize;
}
 
var obj = new Object;
obj.width = 800;
obj.height = 600;
 
var newObj = new Object;
newObj.width = 640;
newObj.height = 500;
 
var objTarg:Object = reSize(obj, newObj, true);
 
trace (objTarg.width+"x"+objTarg.height);

Share
PRINT THIS ENTRY
2 Comments

I ran across a recent entry about MouseWheel events on Mac OS X and Flash by Christian Cantrell and realized there were at least 4 cool implementations that I was aware of. Thought I would list them out here, including a modification I made to one that I have been using and has been around for at least a year or longer now. I really like the anonymous JS function injection approaches that several of them leverage. So here they are:

Takanobu Izukawa of the Spark project:
http://www.libspark.org/wiki/SWFWheel/en
http://www.libspark.org/wiki/SWFSize/en

Gabriel Bucknall – PixelBreaker – AS3.0 MouseWheel on Mac OS X
http://blog.pixelbreaker.com/flash/as30-mousewheel-on-mac-os-x/

Ali Rantakari – Mac OS X Mouse Wheel Support for ActionScript 3 Flash Applications (v.2+)
http://hasseg.org/blog/?p=138

Matt Giger – Simple solution for MOUSE_WHEEL events on Mac
http://blog.earthbrowser.com/2009/01/simple-solution-for-mousewheel-events.html

And here is a link to download a modified version of the JavaScript portion of Gabriel “PixelBreaker” Bucknall’s solution that I worked on to fix a few issues and add some functionality grab it here. I like Gabriels version as he put together an AS2 and AS3 version, it works perfectly with SWFobject 2.1, and with my fixes, multiple items on a page. I had started working on another version that also used externalInterface to leverage the anonymous function injection approach, but given that all three other variations on this issue already provide that functionality, I didn’t want to re-invent the wheel.

Also, note that all these approaches rely on leveraging externalInterface to pass info back forth between the browser/JavaScript and Flash. If AllowScriptAccess is set to NEVER in your embed, none of these projects will work. For what its worth there is a bug thats been logged on Adobes JIRA Bug system here: http://bugs.adobe.com/jira/browse/FP-216 – that is looking for extra votes – it is related to the current inability to reliably detect what AllowScriptAccess and other HTML properties of Flash have been set to. The best solution and request is to make these items available as System.capabilities.xxxx properties available at runtime. That would be great – so make sure you check out the link and vote it up for the next release of the Flash player!

UPDATE 03.10.09 – 12:51AM: I initially uploaded an old version accidentally – doh! I’ve updated the file, which fixes some issues with multiple instances of Flash on a page. Specifically where Flash instances not registered with SWFMacMouseWheel were still preventing the default page/document scroll if you happened to be mousedover them and they were receiving input. I also included a reference to Richard “Rillkill” Rodney for his tweaks for Safari for PC in the JS and AS3 code – which I failed to note requires changes in the AS to support Safari for PC. I also made a quick change to the AS2 version and zipped them both up and added them to the downloads page. If you don’t need Safari for PC support then you can stick with the original AS files from Gabriel/Pixelbreaker. Enjoy!

Share
PRINT THIS ENTRY
3 Comments