Tonight I played with Mozilla Rhino and a few other toys.
Serving webpages dynamically with javascript on the server-side just feels
strange. Ignoring the strange sensation in my brain, the concept of server-side
javascript is a good one.
Client-side web scripting is javascript. Server-side is typically not. This
means input validation and other common code has to be written in two different
languages. This leads to bugs. One language on both ends lets you share lots of
code trivially. Neat.
Comments: 0 (view comments)
Tags: javascript, server side programming
Permalink: /geekery/server-side-javascript
posted at: 04:38
My jquery puffer demo wasn't working in IE. This was the error:
Line 25 is:
top = pos[1];
Turns out 'top' is one of those magically populated objects. In Firefox, you are allowed to assign to top and hence the demo works. In IE, it tells you that assignment is not implemented for that particular object.
In IE, alerting 'top' will show '[object]'. In Firefox, alerting 'top' will show '[object Window]'
If I change my code to use 'top_pos' instead of 'top', the demo works now.
Comments: 2 (view comments)
Tags: javascript, ie
Permalink: /geekery/ie-javascript-error
posted at: 02:10
Last week, I posted
about a new firefox extension I was working on that would let you edit the contents of the urlbar more easily. Well, I have good news. It's alive.
The current incarnation is very basic, but I have some ideas for how to extend
it in the future. I won't go into that now.
This extension adds a menu item to the context menu in the url bar labeled
'Edit URL'. This will bring up a dialog box with a table of key-value pairs
listed. You can edit, add, or delete entries. Clicking 'OK' will modify the url
based on your changes. It automatically unescapes values and re-escapes them later.
Download urledit.xpi
Comments: 1 (view comments)
Tags: firefox, extension, urledit, javascript, xul
Permalink: /geekery/firefox-urledit-20070701
posted at: 04:52
For pimp, I want to be able to search a specific column, say, artist, without
needing multiple fields for searching. The ability to specify more advanced
searches than simple keywords is quite useful. How do we leverage this on the client and turn a search query into a set of key-value pairs?
I must confess I was hesitant to put this kind of logic into Javascript instead
of Python. Furthermore, it makes me feel a little uneasy using /foo/ in
anything other than Perl. Nonetheless, doing this in Javascript was simple and
it's still fast (as it should be).
The particular type of query I want to parse come in the following (hopefully
intuitive) formats:
- foo
- artist:Eminem
- album:"Across a Wire"
- artist:"Counting Crows" album:august
The following code does this for me. The parse_query function will
return a dictionary of query terms. Values are lists.
Here's an example:
- Query
-
rain baltimore artist:"Counting Crows" album:august
- Results of parse_query
-
{ "artist": ["Counting Crows"],
"album": ["august"],
"any": ["rain", "baltimore"],
}
I take the dictionary returned and pass it to jQuery's
$.post function to execute an AJAX (I hate that term, it's such a
misnomer these days) request. Here's the code:
query_re = /(?:"([^"]+)")|(?:\b((?:[a-z:A-Z_-]|(?:"([^"]+)"))+))/gi,
function parse_query(string) {
dict = {}
while (m = query_re.exec(string)) {
val = (m[1] || m[2]).split(":",2)
if (val[1]) { key = val[0]; val = val[1]; }
else { key = "any"; val = val[0]; }
val = val.replace(/"/g,"");
dict[key] = dict[key] || [];
// the following should be .append(val) but
// I don't think javascript lists have them
dict[key][dict[key].length] = val;
}
return dict;
}
Comments: 0 (view comments)
Tags: javascript, rpc, regexp, parsing
Permalink: /geekery/search-query-parsing-in-javascript
posted at: 04:46
The Interface elements plugin for jQuery is super slick. It has a puffer function I want to use. However, the act of 'puffing' makes the element disappear. I want to clone the element and puff the cloned version.
function magicpuff() {
$("img").mousedown(function() {
pos = findPos(this)
left = pos[0];
top = pos[1];
puffer = this.cloneNode(true);
puffer.style.left = left + "px";
puffer.style.top = top + "px";
puffer.style.position = "absolute";
$(document.body).append(puffer);
$(puffer).Puff(1000, function() { $(puffer).remove() });
return false;
})
}
$(document).ready(magicpuff);
This code will duplicate the image clicked placing it directly on top of the
old element. It then puffs the new element and removes it when the puff has
completed. Simple enough.
What good is code without a fun little demo? View the puffer demo
I should note that it seems that the remove portion doesn't always remove the
cloned object. This is especially noticable (though, not visually) when you
activate puffing on more than one image at a time. You need somewhat fast hands
to do this. Firefox's DOM inspector will show you the additional elements
parented by the body tag.
This depends on findPos
available from quirksmode, jQuery, and the forementioned Interface
plugin.
Comments: 5 (view comments)
Tags: jquery, javascript, ui, pimp
Permalink: /geekery/jquery-interface-puffer
posted at: 00:01
This post marks 4 in one day. Whew!
Resig and I were bouncing ideas around after
I made the form filler, and we came up with something that fits very nicely
into the jQuery api (in the form of something very pluggable).
You'll need the following code that will extend jQuery's functionality.
Basically, it adds 'saveAsCookie' and 'loadAsCookie' function calls to
$() objects.
$.fn.saveAsCookie = function(n,t){
return this.each(function(){
createCookie( (n || '') + (this.name || this.id), this.value, t );
});
};
$.fn.loadAsCookie = function(n){
return this.each(function(){
this.value = readCookie( (n || '') + (this.name || this.id) );
});
};
You can safely put that code somewhere and load it anywhere you need autofill. Reusable code is awesome.
Now, we don't want to cache *all* input elements, becuase only some contain
user-input and only some need to be saved. For this, I put the class 'cookieme'
on all input elements I wanted to save.
$(document).ready(function(){
$("form#comments_form").submit(function(){
$("input.cookieme",this).saveAsCookie("formdata");
})
.find("input.cookieme").loadAsCookie("formdata");
});
The arguments to 'saveAsCookie' and 'loadAsCookie' are namespace prefixes. This way, you can avoid namespace collisions with other cookies. All of my autofill cookies will be prefixed with 'formdata' and suffixed with the element name or id attribute.
So, we squished the code down to 6 lines, 4 of which are actually meaningful.
jQuery++
Comments: 5 (view comments)
Tags: jquery, javascript, site, user experience
Permalink: /geekery/jquery-formfill-v2
posted at: 05:38
It's always nice when websites you commonly visit remember things about you, or
atleast give the perception that they remember things about you.
The Pyblosxom comment plugin doesn't autofill the form. That's too bad. I don't
really want to dig into the python code to do any cookie-setting on submission,
becuase I have never looked at the code and thusly am unfamiliar with the
effort required for such a change. Luckily, we can use javascript to store data
in cookies too!
I love jQuery, so that's what I'll use for this little hack. On the comments page, I add the following javascript:
var uname = "u.name";
var uemail = "u.email";
var usite = "u.site";
function saveCommentInformation() {
// Save user information from the form!
createCookie(uname, $("input[@name='author']").val());
createCookie(uemail, $("input[@name='email']").val());
createCookie(usite, $("input[@name='url']").val());
}
function initCommentForm() {
// Autofill user information if available
$("input[@name='author']").val(readCookie(uname));
$("input[@name='email']").val(readCookie(uemail));
$("input[@name='url']").val(readCookie(usite));
// Save comment information when form is submitted
$("form[@name='comments_form']").submit(saveCommentInformation);
}
$(document).ready(initCommentForm);
That's all we need. Whenever someone submits, we will store useful information in a cookie. Whenever that person comes back, we'll pull the data out of the cookie and put it back in the form. User Experience is happier, atleast as far as I am concerned (as a user).
If you are wondering about the 'readCookie' and 'createCookie' functions, you
can find them on quirksmode.org:
http://www.quirksmode.org/js/cookies.html
Comments: 14 (view comments)
Tags: jquery, javascript, site, user experience
Permalink: /geekery/jquery-formfill-v1
posted at: 01:52
Yesterday, I participated in a 12-hour coding-binge competition. It started at
7pm Friday night and ran until 7am Saturday morning. It was fueled by Computer
Science House and Bawls, both sponsors of the event. Needless to say, I haven't
gotten much sleep today.
The competition website is here. Go there if you
want to view this year's objectives.
The Dream Team consisted of John Resig, Darrin
Mann, Matt Bruce, and myself. Darrin, Resig, and I are all quite proficient at
web development, so we decided this year we would represent ourselves as "Team
JavaScript" - and do everything possible in javascript. Bruce is not a
programmer, but I enlisted his graphical art skills because I figured with our
team doing some web-based project, we definitely needed an artist.
After reviewing all the objectives, we came up with a significant modification
upon the Sudoku objective. The sudoku objective was a problem that lacked much
room for innovation, so we went further and instead of solving Sudoku, wrote a
web-based version of an extremely popular game in Second Life. The contest
organizer approved of our new objective, so we did just that.
Resig worked on game logic, I worked on chat features, Darrin worked on scoring
and game generation, and Bruce worked on the interface graphics. Becuase our
tasks were all mostly unrelated, we could develop them independently. Most of
the game was completed in about 6 hours, and the remainder of the time was
spent fixing bugs, refactoring, and some minor redesign.
The backends were minimal. The chat backend was only 70 lines of perl, and the
score backend was 9 lines of /bin/sh. Everything else was handled in the
browser. We leveraged Resig's jQuery to make development faster. Development
went extremely smooth, a testament to the "Dream Team"-nature of our team,
perhaps? ;)
The game worked by presenting everyone with the same game - so you can compete
for the highest score. You could also chat during and between games, if you
wanted to.
A screenshot can be found here. At the end of the competition, we only had one
known bug left. That bug didn't affect gameplay, and we were all tired, so it
didn't get fixed. There were a few other issues that remained unresolved that
may or may not be related to our code. Firefox was having issues with various
things we were doing, and we couldn't tell if it was our fault or not.
Despite the fact that I probably shouldn't have attended the competition due to
scholastic time constraints, I was glad I went. We had a blast writing the game.
We may get some time in the near future to improve the codebase and put it up
online so anyone can play. There are quite a few important features that need to
be added before it'll be useful as a public game.
Comments: 1 (view comments)
Tags: nosleep, perl, javascript, web2.0, jquery, shell, web, xml, codebinge
Permalink: /geekery/bawls-competition-tringo
posted at: 19:11
I recieved a report from someone about the keyboard widgety thing I wrote not
working under IE. I took this as an opportunity to rewrite it slightly. The end
result is that it is completely object-oriented now and works in Firefox, IE,
and Opera.
The new version makes use of addEvent written by Dean Edwards. I was very
pleased with it's cross-browserness :)
projects/kioskweb/demo/keyboard.html
Comments: 3 (view comments)
Tags: javascript, keyboard widget
Permalink: /web/204
posted at: 21:03
|
Search this site
Navigation
Metadata
Home
About
Resume
My Code (SVN Web)
ARP Security
Dynamic DNS with DHCP
OpenLDAP+Kerberos+SASL
PPP over SSH
SSH Security: /bin/false
Week of Unix Tools
Work Efficiency
fex
firefox tabsearch
firefox urledit
grok
keynav
liboverride
newpsm (FreeBSD)
nis2ldap
pam_captcha
poor man's backup
Solaris audio utility
xboxproxy
xdotool
xmlpresenter
xpathtool
misc scripts
Presentations
Yahoo! Hack Day '06
Unix Essentials
Vi/Vim Essentials
Tag Cloud
Calendar
Friends
BarCamp
Kent Brewster
Tantek Çelik
John Resig
Wesley Shields
Tyler Shields
Technorati
|