Reading Ajaxian Blog today and came across some very handy JavaScript. It's a great shortcut. It originated from DWR and they deserve all the credit. I'm just passing it along for those who have not seen it before.
function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string') {
if (document.getElementById) {
element = document.getElementById(element);
}
else if (document.all) {
element = document.all[element];
}
}
if (arguments.length == 1) {
return element;
}
elements.push(element);
}
return elements;
}
So, instead of:
document.getElementById('elementName')
You can:
$('elementName')
I'm gonna start using this in all of my JavaScript!
Thursday, June 30, 2005
Shortcut document.getElementById
Microsoft Gator
Here's some interesting news... As if enough people don't already think that Microsoft is Big Brother, and out to get all of your information, here's more fuel for the fire. Apparently, Microsoft is in talks with Claria, maker of the treacherous Gator software. I'm not sure why they would want this. Some say its for some other piece of software that Claria makes, but I'm not so sure.
I'm not one who typically makes an outcry over Microsoft's business tactics. I don't care much for the Windows platform, and prefer to use Mac, but business-wise, Microsoft are some of the best. But, because of this, they are very good at using the information that they have to make more money. So, it makes sense for them to collect information from users, and then turn around, and put that information to use to make money.
It'll be interesting to see how all of this pans out in the end.
Wednesday, June 29, 2005
Maximum MaxLength
I came across an interesting quirk with Firefox today. Don't even ask why or how, but I found that the maximum MaxLength for a textbox rendered in Firefox is
(2^26) - 1
For the math illiterate, that equates to 67,108,863. If you set the MaxLength to anything higher than this and render the textbox in Firefox, you will not be able to enter anything into the textbox.
You can try it yourself. Here's a couple samples:
<input id="validTextbox" maxlength="67108863" type="text" value="">
<input id="invalidTextbox" maxlength="67108864" type="text" value="">
Update: Opera has the same limitation as Firefox.
Tuesday, June 28, 2005
Delete "Save"
Read an interesting blog entry by Lars Pind today. No idea who this fellow is, but I think his idea is nuts. He has the notion that each application should auto-save data every minute or so. The theory sounds ok at first, but upon closer examination it really doesn't work.
What if the user doesn't want to save something? He has the notion that if you enter something in an application, you wanted to save it. While this might be true most of the time, its not always the case. For example, I routinely copy several items into a text editor for reference later, but I have no intention of keeping them around. This text-editing app might be open all day with these items, but at the end of the day, I close the application, and DON'T SAVE the data. In his scenario this data would be saved. But where? And what if I do this everyday, and I copy lots of stuff? I end up wasting drive space, filling it with all sorts of files that I don't want or need.
And also along these lines, when does the file get a name? When the application starts? Does that mean I now have the extra step to name something that I don't plan on keeping and don't need?
While I agree there are times that auto-save works, I disagree that EVERY application should implement it.
Monday, June 27, 2005
Bookmarked
I have been bookmarked! Well, my Code2HTML widget has. And the best part is that I have no idea who this person is. I just think it's cool that someone else found my software useful enough to bookmark its homepage. If you are interested, you can find a list of those who have bookmarked its website by visiting here.
Update (07-28-2005 2:55pm): There are now have 2 users who have bookmarked Code2HTML on del.icio.us
The Phone That Won't Quit
Wednesday, June 22, 2005
Personal Jesus
The past few days, the radio station I listen to most often has been playing "Personal Jesus" by Depeche Mode. Listening to it on the way home yesterday, I got to thinking. Here's a snippet of the lyrics:
Your own personal jesus
Someone to hear your prayers
Someone who cares
Your own personal jesus
Someone to hear your prayers
Someone who’s there
I'm not sure, but I think the song is referring to the tele-evangelists, poking fun at them. But listening to it on the way home, I got to thinking about the name "Personal Jesus". As Christians, we each have our own "Personal Jesus". Jesus cares, and Jesus is there for each one of us, personally. All we have to do is call.
Matthew 28:20 "...I am with you always, even to the end of the age."
J Giles Band Smurf Connection
Listening to the radio this morning, the DJ on there made a comment about how the whistle at the end of the J Giles Band song "Centerfold" sounds somewhat similar to the Smurfs whistle. And I have to admit, it is quite similar. Maybe, just maybe, after a late night of recording, the band sat down, and the Smurfs were on, and someone thought, "Hey! Let's use this, and see if anyone notices...."
Tuesday, June 21, 2005
Overcoming the 4,096 Byte Limit of widget.system
Update 06-22-2005 9:50pm: I have found a way that works for overcoming the nothing in the clipboard bug. Here's the modification for executeSystemCommand:
function executeSystemCommand(cmd) {
var out;
out = widget.system(cmd + " | wc -c", null).outputString;
out = parseInt(out, 10);
if (out > 0) {
widget.system(cmd + " > output.txt", null);
out = readInFile("output.txt");
widget.system("/bin/rm output.txt", null);
return out;
}
return null;
}
What this does is is to execute the desired command capturing the count of characters, and if the count is nothing, then we simply return null. If the count is greater than zero, we execute the command and redirect the output to a file, and then read the file using XmlHttpRequest. This gets around both the 4,096 character limit, and the empty clipboard problem, if you happen to be using /usr/bin/pbpaste.
Update 06-22-2005 7:55am: A little more testing revealed that I couldn't use the 4095 length. I adjusted it to 1, but there is still more testing that needs to be done before I can be sure about this. What I find odd is that the pbpaste command fails within widget.system when there is nothing on the clipboard. It doesn't fail in the terminal. Here's the corrected line from the executeSystemCommand function:
widget.system(cmd + " | tail -c 1", null).outputString;
Update 06-21-2005 11:35pm: I did a little more testing and found in the rare case that the clipboard is empty, the sample code has a slight bug. Here's a correction to the executeSystemCommand:
function executeSystemCommand(cmd) {
var out;
out = widget.system(cmd + " | tail -c 4095", null).outputString;
if (out.length == 0) return null;
widget.system(cmd + " > output.txt", null);
out = readInFile("output.txt");
widget.system("rm output.txt");
return out;
}
I ran into the limit of widget.system while working on the next version of the Code2HTML widget. Apparently, output captured from calls to widget.system are limited to 4,096 bytes. If the command returns more than that, it crashes the widget. Lovely, just lovely. I'm not sure why the Apple engineers would do this, but what's done is done. Hopefully, they'll fix that in a future release, but until then, you can use the following JavaScript in your widgets. This bit of JavaScript is not new with me. I found this code over at Dashboard Widgets in this forum. Kudos to the original author. I did create a new JavaScript function that does a little more work than the original posting.
function executeSystemCommand(cmd) {
widget.system(cmd + " > output.txt", null);
var out = readInFile("output.txt");
widget.system("rm output.txt");
return out;
}
function readInFile(filename) {
req = new XMLHttpRequest();
req.open("GET", filename ,false);
req.send(null);
response = req.responseText;
if (response) {
return response;
}
return null
}
To use this, do something like the following:
executeSystemCommand("/usr/bin/pbpaste");
Monday, June 20, 2005
Disney's New Ride Screening Process
In case you have not heard, Disney has a new screening process that you must go through in order to enjoy the rides. More information can be found here.
Downside of Owning a Mac
Update 06-22-2005: Version 1.1 Released. Screenshots have been updated below. You can download the latest version from here.
I have posted a couple of screenshots of the work-in-progress for the next release of the Code2HTML widget. With this release, I am focusing on making the widget conform to the Apple guidelines for widgets, and also, am adding a little bit of functionality.
I took the scroller javascript provided by Apple with the development kit, and modified it to create a horizontal scroller. It took more time than I had originally expected, and the end result was that I stayed up way too late last night. I guess that would be the only downside to owning a Mac. They are too much fun!
Here's the screenshots of the next version. It should be available later this week.

Saturday, June 18, 2005
Friday, June 17, 2005
Code2HTML Website Online
I finally got around to posting my widget for download. You can find the Code2HTML widget by visiting its website. Its home on the web is not much to look at right now. I just wanted to make it available for consumption by the public. I also submitted it to Apple for inclusion in their Widgets collection. As I make enhancements and fix bugs, I will post new versions on the website.
If you want the source for the widget, simply download the package from the website, unzip the package, control-click on the widget, and select Show Package Contents.
Thursday, June 16, 2005
Hold the Button
Just came across one of the strangest things.
HoldTheButton.COM
Basically, you click-and-hold the mouse button for as long as you can. I managed to hold the button longer than 5.4% of others who have tried, but the most bizarre thing was that the longest time for anyone was over 17 hours!
That's insane!!
Whoever accomplished that should try out for Survivor.
Wednesday, June 15, 2005
Wasting Tax Dollars
Outside the office where I work, the sidewalk has been rebuilt over the past few months. During that time, there has been this one county vehicle that shows up periodically, usually blocking traffic in the parking lot adjacent to the sidewalk. The work on the sidewalk is not really a waste of tax dollars. It needed repaired. The fellow who shows up in the county vehicle is where my issues begin.
First, the vehicle is a Dodge Durango... a $30,000 vehicle for a county worker. Second, the vehicle is a gas guzzler. Third, the one guy is the only one in the vehicle. Fourth, its a new vehicle. So, we have an expensive vehicle (paid for my tax dollars). Its an expensive, new vehicle (paid for by my tax dollars). Its an expensive new vehicle that is not fuel efficient (paid for by my tax dollars). And not only that, it is hauling a single passenger!
Wasting tax dollars at it's finest. I'm sure there are others out there who have witnessed the same wastefulness where you live. It's time I think that we stood up, and voted these wasteful politicians out the door.
Tuesday, June 14, 2005
Death at Disney
I heard today about a tragedy that occurred at Epcot at Disney World in Orlando, FL. Apparently a 4 year old boy was pronounced dead at a local hospital in Orlando, FL after being found limp and near lifeless on the Mission:Space ride.
Apparently, the mother and this young boy got on the ride, and while riding, the mother noticed that her son's leg were sticking straight out and that he appeared to be very frightened. After the ride stopped, she found her son to be limp and near lifeless. The mother, a Disney worker, and paramedics tried to revive the boy He was later pronounced dead at a hospital in the Orlando area.
There are a few thing about this story that I find interesting. First that a mother would take a 4 year old on such a ride. I won't ride it, and I am 31. I ride all of the big thrill roller coasters, but have no desire to spin and puke. Those rides just leave me feeling very ill. I can only imagine the strain on a person of not very good health, or one, as in this case, is very young. I have a 5 year old daughter, and there is NO WAY she would ever get on that ride. I really don't understand a mother who would do that. I am sure though that she is regretting the decision very much, and my prayers will be with this mother and the family of this young boy.
The other interesting aspect of this story is that the father works for the United Nations. I am just waiting for the MSM (main stream media) to start the finger pointing at the President. After all, they did blame him for the hurricanes in Florida. You may think I am a conspiracy theorist, but just wait. You'll see. If they don't, I will be most surprised, and relieved.
Reginald Barkley Syndrome
A friend of mine and I were discussing video games and their impact on our society. He creates video games for a living, and lives in Japan, so he has an interesting view on the topic.
We were discussing how many times today, individuals will immerse themselves so deeply into games that the games become their reality. They cut themselves off from everything and everyone not directly involved with the game. We went on to talk about how that happens with the Internet as well.
My friend noted that he has come to call that the "Reginald Barkely Syndrome", after the Star Trek character. Lt. Barkley spent most of his time in the Holodeck of the Enterprise. He preferred that to interaction with real folks. He enjoyed his fantasy world, where he seemed to have more control. The same is true today of those who cut themselves off from everyone, even those who live in the same house, and rather communicate with folks they do not know, except through internet chat rooms, or online games.
We are becoming such a disconnected world. The inernet has brought us closer than ever before, and yet at the same time, has brought us so far apart. How many of you know your next door neighbors? Of those of you that don't, how many know someone you met in an internet chat room, but have never met face-to-face?
Why don't we make an effort to get to know our neighbors? I think the world could be a much better place if we all took a little time to get to know one another.
Friday, June 10, 2005
Here A Bug, There A Bug, Everywhere A Bug
I have had my fill today of .NET flaws, bugs, features, or whatever you want to call them. Disabled controls do not have their values persist during post-back. Now, that is just ridiculous!
A Day Full Of "Features"
I created some javascript that I wanted to fire on a text input when its value changed. The javascript that I wrote took the value of the text input and formatted it. In addition, on this same text input I created a custom validator, with client-side validation enabled. I created the needed javascript for the client-side validation. I open my page and begin to do a little testing. This is when I find the "feature".
Opening WebUIValidation.js (Microsoft's javascript library that makes all of the client-side validation of controls possible), I find the following snippet:
var ev;
if (control.type == "radio") {
ev = control.onclick;
} else {
ev = control.onchange;
}
if (typeof(ev) == "function" ) {
ev = ev.toString();
ev = ev.substring(ev.indexOf("{") + 1, ev.lastIndexOf("}"));
}
else {
ev = "";
}
var func = new Function("ValidatorOnChange(); " + ev);
if (control.type == "radio") {
control.onclick = func;
} else {
control.onchange = func;
}
Microsoft hooks their validation in so that it is called BEFORE any custom javascript that you may add to the onchange event of a control. Had they simply appended their validation function, their end would function as always, and developers would get expected results. In my case, it just so happened that the client-side javascript I added formatted the value in a way that made it valid. So, in my case, I enter some text, press the tab key, Microsoft's validation function fires, says that the entered text is invalid. Then, my custom formatting javascript fires, and the text is formatted. However, the validation is not performed again since the onchange doesn't fire when text is altered programatically. So, I have valid data, but the invalid message is still showing. Even worse, I can press the submit button, and it fires, since the data is actually valid. Very confusing for an end-user.
Javascript Multiplication Bug
Sometimes it just doesn't pay to even try. Found a bug in the javascript multiplication engines of Internet Explorer, Mozilla, Opera, and who knows how many other browsers. Now, maybe I am just doing something wrong, but......
Try this with javascript:
alert(10 * 25.01);
It returns 250.10000000000002 ?!?!?!?!
Now, tell me why does that not return a value of 250.1 ?
AJAX.Net
Hearing all the latest hype on AJAX, I had to see what it was all about. Well, it turns out it is nothing more than using the XmlHttpRequest object to do some server-side processing from client-side javascript without having to post-back to the server. I've been doing some of that for a while now, but nothing very complicated.
Today, googling for something completely different, I stumble across AJAX.Net, and I have a completely renewed interest in XmlHttpRequest. This guy has implemented the interface that I have always wanted, but never felt compelled enough to write on my own. Suffice to say there'll be more written here on this topic!
Thursday, June 09, 2005
SqlCommandBuilder.DeriveParameters
Today, I ran into a problem with a difference between ADO and ADO.NET. In ADO, when you created a command object for executing a stored procedure, and added the parameters, the parameter names were ignored. Position is what mattered. With ADO.NET, parameter names when provided (and they have to be) matter. But thanks to Google and a little perseverance, I was able to find the answer I needed -- SqlCommandBuilder.
Using the following code, you can populate the Parameters SqlParameter collection of a command with all of its defined parameters.
SqlCommandBuilder.DeriveParameters(pCommand);
It's simply wonderful! Kudos to MS for providing this class, even though I still think I should be able to create a SqlCommand object and supply it's parameters based on position, without having to resort to an EXEC statement.
Tuesday, June 07, 2005
What If Two Programs Did This? (My Take)
Reading this today, I quickly thought of something similar. Windows Media Player file associations. I was working on a project where we were implementing a custom installation of the WebTop interface to Documentum, and we ran into a similar problem. We wanted to use a custom player for .WAV files when the user clicked a link in the WebTop interface. Documentum provided a hook so that the content was downloaded to the user's machine, and would then launch the associated application. Problem was, though, that changing the file association in Windows Explorer was not enough. It seemed to work, at first. You would change the file association in Windows Explorer, double-click on a .WAV file, and the new media player would load as expected. However, clicking on the link from WebTop, however, still launched Windows Media Player. Turns out that Windows Media player sets itself as the default in another part of the registry as well. So, to get around the problem, you had to unassociate Windows Media Player from within the Windows Media Player preferences, then go to Windows Explorer, and setup the new association.
So, when I read this, I had to laugh. Here, a MS guy is saying not to do the very thing that a Windows app is doing, though not quite as annoyingly as the products he is discussing. Same root problem though -- Taking choice away from the user!
LoadControl and HttpHandler
Yesterday, I found another interesting, shall we say "feature", of the .NET framework. I had a page class that derived from System.Web.UI.Page. In this page, I loaded a custom control. As a result of this custom control loading, a call is made to Page.LoadControl to load a user control into the page. All of this worked fine, until I decided that wanted to define an httpHandler in my web.config to load my custom page class. When I did that, my call to LoadControl would fail, and would inform me that I was trying to load a control from another application.
My LoadControl looked something like:
Page.LoadControl("content/stuff/MyControl.ascx");
Thanks to Thomas Zumbrunn over at CodeProject, I found an interesting workaround that allows you to load controls from "other applications". In his case, he really did want to load controls in other web applications. I simply wanted to load controls that resided in a folder in my current application, but I wanted to do so when the page was loaded via the httpHandler directive in web.config.
What I ended up with looked something like:
Page.LoadControl("~/content/stuff/MyControl.ascx");
Subtle, but it works. And it works both ways. I can load my page by creating an ASPX page instance that derives from my custom page class, or I can load my custom page class using the httpHandler directive in web.config.
Personally, I think that this is a bug in the .NET framework, but one that I doubt Microsoft will fix. I just wish they would at least document it in the documentation for LoadControl. C'mon Microsoft, get with the program!
Apple's Going to use Intel Processors
I just got a Mac Mini, but I say more power to them!! It means cheaper hardware in the future for me, and it means more software in the future for me. Win-win I think. Apple's hardware sales may go down, but not much. They have a great design team, and I have yet to see any PC manufacturer rival their elegant and pleasing stylistic designs. Three cheers to Apple!
Monday, June 06, 2005
Code2HTML Widget Update
I updated the source to the Code2HTML widget. You can find the udpates here. I am planning on releasing the widget on Apple's website here in the very near future. Look for an update here to the link to download the package in the next few days,
Saturday, June 04, 2005
Blog Formatting
Well, after posting the source to my widget, I quickly realized a new feature that my code convertor needs -- managing the non-break spaces in a more sensible manner. I am going to tweak it so that it only converts groups of spaces greater than 1 space. This should allow it to wrap in a sane fashion.
Code2HTML Widget
Update (06 - 06 - 2005 11:13pm) :Updated source with a few changes. Helps to alleviate the problem with white space and text-wrapping. There are a few more options now, including inserting spaces around braces, parentheses, and insertting spaces after commas. These changes help to take care of most, if not all, text-wrapping issues for most source code.
I finally got around to completing my widget. I worked for a while on trying to create the editing area as a contentEditable DIV, but finally gave up. There just isn't enough documentation on it. I got it work, but the scrolling didn't happen automatically like it does with the TEXTAREA, so I gave up, and broke Apple's user interface guidelines for widgets. Oh well, at least it functions.
When you create a widget for the Dashboard, there are a few files that must be created. These are the following:
Widget HTML - defines the layout using HTML
Widget CSS - defines the properties and stylistic elements
Widget Javascript - defines the behavior of the widget
Info.plist - widget bundle properties
Widget Background - image that comprises the body of the widget
Widget Preferences Background - image that comprises the body of the widget's preferences
Widget Icon - image for the icon in the widget tray of the dashboard
My widget, as you know if you are a regular reader, converts source code for inclusion in HTML markup. Its pretty simplistic right now, but functional enough for my needs. Currently, it supports converting spaces to non-breaking spaces, converting tabs to a variable number of non-breaking spaces, converting newlines to breaks, and converts the <, >, and & characters.
Ok, enough babbling. Here's the source for the files that make up this widget. Explanation of the source will follow in a future post.
"Code2HTML.html"
<html>
<head>
<!-- The style sheet should be kept in a separate file; it contains the design for the widget -->
<style type="text/css">
@import "Code2HTML.css";
</style>
<!-- The JavaScript file contains the logic needed for this widget -->
<script type='text/javascript' src='Code2HTML.js' charset='utf-8'></script>
<script type='text/javascript' src='file:///System/Library/WidgetResources/button/genericButton.js' charset='utf-8'></script>
</head>
<body onload='setup ( ) ;'>
<div id="front" onmousemove='mousemove ( event ) ;' onmouseout='mouseexit ( event ) ;'>
<!-- front side here -->
<img src='Default.png'>
<textarea wrap="off" id="codeField"></textarea>
<div class='flip' id='flip' onclick='showBack ( event ) ;' onmouseover='enterflip ( event ) ;' onmouseout='exitflip ( event ) ';></div>
<div class="convertButton" id="convertButtonDiv"></div>
<div class="revertButton" id="revertButtonDiv"></div>
<div class='flip' id='fliprollie'></div>
<!-- end front side -->
</div>
<div id="back">
<!-- reverse side here -->
<img src='Back.png'>
<input type="checkbox" id="convertNewlines" />
<div id="convertNewlinesLabel">Convert Newlines To Breaks</div>
<input type="checkbox" id="convertTabs" checked="checked"/>
<div id="convertTabsLabel">Convert Tabs To</div>
<input type="text" id="tabSize" value="4" size="2" maxlength="2" /><div id="tabSizeLabel">Spaces</div>
<input type="checkbox" id="convertSpaces" checked="checked" /><div id="convertSpacesLabel">Convert Spaces To Non-Breaking Spaces</div>
<input type="checkbox" id="convertParens" checked="checked"/>
<div id="convertParensLabel">Insert Spaces Around Parentheses</div>
<input type="checkbox" id="convertBraces" checked="checked"/>
<div id="convertBracesLabel">Insert Spaces Around Braces</div>
<input type="checkbox" id="convertCommas" checked="checked"/>
<div id="convertCommasLabel">Insert Spaces After Commas</div>
<div class="doneButton" id="doneButtonDiv"></div>
<!-- end reverse side -->
</div>
</body>
</html>
"Code2HTML.css"
body {
margin: 0;
font-family: verdana;
font-size: 9pt;
}
.convertButton {
position: absolute;
bottom: 28px;
left: 180px;
}
.revertButton {
position: absolute;
bottom: 28px;
left: 180px;
display: none;
}
#codeField {
padding: 3px;
position: absolute;
top : 40px;
left: 40px;
width: 340px;
height: 330px;
}
#convertNewlines {
position: absolute;
top: 50px;
left: 30px;
}
#convertTabs {
position: absolute;
top: 100px;
left: 30px;
}
#convertSpaces {
position: absolute;
top: 150px;
left: 30px;
}
#tabSize {
position: absolute;
top: 95px;
left: 150px;
}
#tabSizeLabel {
position: absolute;
top: 100px;
left: 180px;
}
#convertTabsLabel {
position: absolute;
top: 100px;
left: 50px;
}
#convertSpacesLabel {
position: absolute;
top: 150px;
left: 50px;
}
#convertNewlinesLabel {
position: absolute;
top: 50px;
left: 50px;
}
#convertParens {
position: absolute;
top: 180px;
left: 30px;
}
#convertParensLabel {
position: absolute;
top: 180px;
left: 50px;
}
#convertBraces {
position: absolute;
top: 210px;
left: 30px;
}
#convertBracesLabel {
position: absolute;
top: 210px;
left: 50px;
}
#convertCommas {
position: absolute;
top: 240px;
left: 30px;
}
#convertCommasLabel {
position: absolute;
top: 240px;
left: 50px;
}
.flip {
position:absolute;
bottom:30px;
right:30px;
width:13px;
height:13px;
}
#flip {
opacity:0;
background:url ( file:///System/Library/WidgetResources/ibutton/white_i.png ) no-repeat top left;
z-index:8000;
}
#fliprollie {
display:none;
opacity:0.25;
background:url ( file:///System/Library/WidgetResources/ibutton/white_rollie.png ) no-repeat top left;
z-index:7999;
}
#back {
display:none;
}
.doneButton {
position:absolute;
bottom:30px;
left:30px;
}
"Code2HTML.js"
var code = "";
function setup ( )
{
createGenericButton ( document.getElementById ( 'convertButtonDiv' ) ,
"Convert", convert ) ;
createGenericButton ( document.getElementById ( 'revertButtonDiv' ) ,
"Revert", revert ) ;
createGenericButton ( document.getElementById ( 'doneButtonDiv' ) ,
"Done", hideBack ) ;
loadPrefs ( ) ;
return 0;
}
function loadPrefs ( )
{
if ( window.widget )
{
widget.setPreferenceForKey (
document.getElementById ( 'tabSize' ) .value,
"tabSize" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertTabs' ) .checked,
"convertTabs" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertNewlines' ) .checked,
"convertNewlines" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertSpaces' ) .checked,
"convertSpaces" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertParens' ) .checked,
"convertParens" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertBraces' ) .checked,
"convertBraces" ) ;
widget.setPreferenceForKey (
document.getElementById ( 'convertCommas' ) .checked,
"convertCommas" ) ;
}
}
function savePrefs ( )
{
if ( window.widget )
{
document.getElementById ( 'tabSize' ) .value =
widget.preferenceForKey (
"tabSize" ) ;
document.getElementById ( 'convertTabs' ) .checked,
widget.preferenceForKey (
"convertTabs" ) ;
document.getElementById ( 'convertNewlines' ) .checked,
widget.preferenceForKey (
"convertNewlines" ) ;
document.getElementById ( 'convertSpaces' ) .checked,
widget.preferenceForKey (
"convertSpaces" ) ;
document.getElementById ( 'convertParens' ) .checked,
widget.preferenceForKey (
"convertParens" ) ;
document.getElementById ( 'convertBracees' ) .checked,
widget.preferenceForKey (
"convertBraces" ) ;
document.getElementById ( 'convertCommas' ) .checked,
widget.preferenceForKey (
"convertCommas" ) ;
}
}
function revert ( )
{
document.getElementById ( 'codeField' ) .value = code;
document.getElementById ( 'codeField' ) .readOnly = false;
document.getElementById ( 'revertButtonDiv' ) .style.display = "none";
document.getElementById ( 'convertButtonDiv' ) .style.display = "block";
}
function convert ( )
{
var html;
code = document.getElementById ( 'codeField' ) .value;
html = code.replace ( /&/g, "&" ) ;
html = html.replace ( /</g, "<" ) ;
html = html.replace ( />/g, ">" ) ;
if ( document.getElementById ( 'convertSpaces' ) .checked )
{
html = html.replace ( /\ \ /g, " " ) ;
html = html.replace ( /\ \ /g, " " ) ;
}
if ( document.getElementById ( 'convertCommas' ) .checked )
{
html = html.replace ( /\, /g, ", " ) ;
}
if ( document.getElementById ( 'convertParens' ) .checked )
{
html = html.replace ( /\ ( /g, " ( " ) ;
html = html.replace ( /\ ) /g, " ) " ) ;
}
if ( document.getElementById ( 'convertBraces' ) .checked )
{
html = html.replace ( /\ { /g, " { " ) ;
html = html.replace ( /\ } /g, " } " ) ;
}
if ( document.getElementById ( 'convertTabs' ) .checked )
{
var tabSpaces = "";
for ( var i = 0; i < document.getElementById ( 'tabSize' ) .value; i++ )
tabSpaces += " ";
html = html.replace ( /\t/g, tabSpaces ) ;
}
if ( document.getElementById ( 'convertNewlines' ) .checked )
html = html.replace ( /\n/g, "<br/>\n" ) ;
document.getElementById ( 'codeField' ) .value = html;
document.getElementById ( 'convertButtonDiv' ) .style.display = "none";
document.getElementById ( 'revertButtonDiv' ) .style.display = "block";
document.getElementById ( 'codeField' ) .readOnly = true;
}
function showBack ( )
{
var front = document.getElementById ( "front" ) ;
var back = document.getElementById ( "back" ) ;
if ( window.widget )
widget.prepareForTransition ( "ToBack" ) ;
front.style.display="none";
back.style.display="block";
if ( window.widget )
setTimeout ( 'widget.performTransition ( ) ;', 0 ) ;
}
function hideBack ( )
{
var front = document.getElementById ( "front" ) ;
var back = document.getElementById ( "back" ) ;
if ( window.widget )
widget.prepareForTransition ( "ToFront" ) ;
back.style.display="none";
front.style.display="block";
if ( window.widget )
setTimeout ( 'widget.performTransition ( ) ;', 0 ) ;
savePrefs ( ) ;
}
var flipShown = false;
var animation = { duration:0, starttime:0, to:1.0, now:0.0, from:0.0, firstElement:null, timer:null } ;
function mousemove ( event )
{
if ( !flipShown )
{
if ( animation.timer != null )
{
clearInterval ( animation.timer ) ;
animation.timer = null;
}
var starttime = ( new Date ) .getTime ( ) - 13;
animation.duration = 500;
animation.starttime = starttime;
animation.firstElement = document.getElementById ( 'flip' ) ;
animation.timer = setInterval ( "animate ( ) ;", 13 ) ;
animation.from = animation.now;
animation.to = 1.0;
animate ( ) ;
flipShown = true;
}
}
function mouseexit ( event )
{
if ( flipShown )
{
// fade in the info button
if ( animation.timer != null )
{
clearInterval ( animation.timer ) ;
animation.timer = null;
}
var starttime = ( new Date ) .getTime ( ) - 13;
animation.duration = 500;
animation.starttime = starttime;
animation.firstElement = document.getElementById ( 'flip' ) ;
animation.timer = setInterval ( "animate ( ) ;", 13 ) ;
animation.from = animation.now;
animation.to = 0.0;
animate ( ) ;
flipShown = false;
}
}
function animate ( )
{
var T;
var ease;
var time = ( new Date ) .getTime ( ) ;
T = limit_3 ( time-animation.starttime, 0, animation.duration ) ;
if ( T >= animation.duration )
{
clearInterval ( animation.timer ) ;
animation.timer = null;
animation.now = animation.to;
}
else
{
ease = 0.5 - ( 0.5 * Math.cos ( Math.PI * T / animation.duration ) ) ;
animation.now = computeNextFloat ( animation.from, animation.to, ease ) ;
}
animation.firstElement.style.opacity = animation.now;
}
function limit_3 ( a, b, c )
{
return a < b ? b : ( a > c ? c : a ) ;
}
function computeNextFloat ( from, to, ease )
{
return from + ( to - from ) * ease;
}
function enterflip ( event )
{
document.getElementById ( 'fliprollie' ) .style.display = 'block';
}
function exitflip ( event )
{
document.getElementById ( 'fliprollie' ) .style.display = 'none';
}
"Info.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>Code2HTML</string>
<key>CFBundleIdentifier</key>
<string>net.4haks.code2html</string>
<key>CFBundleName</key>
<string>Code2HTML</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CloseBoxInsetX</key>
<integer>5</integer>
<key>CloseBoxInsetY</key>
<integer>5</integer>
<key>MainHTML</key>
<string>Code2HTML.html</string>
</dict>
</plist>
That's it for now. I'll try and go into some of the more interesting details of this code in a future post.
Friday, June 03, 2005
Google AdSense
I have taken the plunge, and decided to get some advertising dollars. Hopefully, the ads will be useful, and not distracting. I guess only time will tell.