Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Sunday, October 12, 2008

Firebug Console for power users == REPL

There have been many, many posts through out the internet explaining why Firebug is the greatest thing ever for the web developer from the CSS editor to the AJAX transmission viewer to the javascript debugger. I'm going to throw one more thing in; javascript REPL.


REPL stands for Read, Evaluate, Print, Loop for those that don't know and basically means it's an interactive shell into your program. Most of us know about the console in Firebug but how many know about the power it gives? When you open Firebug the console tab is selected by default. You may know this as the place those console.log() messages go. At the bottom is a blank line denoted by ">>>", this is the interactive part. You can execute a line of javascript here. If you click the circle with the up arrow on the right you open the multiline console. I recommend this as the way to go. You can write multiple lines, such as functions, and execute with ctrl-enter or command-enter.


Anyway, back to that REPL. The console lets you interact with any loaded javascript on the page. You can change global variables, call functions, pretty much anything javascripty. This is where the power comes in. You can define functions meaning you can redefine functions! And it'll work when some element or function on the page calls it.


Imagine for a moment that your trying to create a new function or debug a function on your production server where you have to interact with the real data. You can't just change the code, check it in, build and deploy each time due to various issues like time and the client noticing the site going up and down. What you can do, and what I had to do recently, is open the console, paste in the fixes to the definition of the function, evaluate it, and then go about interacting with the page. It becomes a much faster solution that has a couple of benefits.

  1. No redeploy until you know it works
  2. Don't have to worry about anyone else getting in there and using your code while you're testing it out
  3. Interaction with the real problem, with the real data causing it.


If you go about writing your javascript code with the console in mind there are some great uses for it.

  • Have your logging statements controlled by a global variable. On the page it's false and not printing. When you need to see what's going on in Production or some other uncontrolled by you environment, just change that variable to true and you get your logging.
  • Fire functions and events while developing so you don't have to keep reloading the page and waiting for template recompiles. I like to use this when writing something with AJAX calls while working on the backend. I create a refresh() method ,that is the initial loader on the page anyway, and call it from the console.
  • Last, but not least, a personal favorite, testing out javascript expressions. We all have been there where you can't remember exactly how substring() works and you'd just like to try on the page instead of googling it and then interpreting what you find to fit your scenario. I use this all the time for things like figuring out a complex Prototype.js expression on the page to see how it works and tweet it before putting it on the page for real and going through the refresh cycle. In fact I'd go as far to say it'd be very, very hard to do without and I'm starting to wish for one in Java (aside from things like groovysh and jirb)

I hope this opens up some options and makes life easier for you developers out there. At least when working in Firefox. Firebug does have the downside of making you feel that much more helpless when you have some stupid IE bug.

Saturday, July 19, 2008

T-Mobile Address Manager export "Hack"

Edit: Thanks to yincrash for pointing out that they changed their namespace on this object to TMO.ABPORTAL.



My friend Candice got a 1st Gen iPhone on the cheap and needed to get her numbers from T-Mobile's new online Address Manager (TAB). It does syncing to and from a regular T-Mobile phone but the iPhone isn't a regular T-Mobile Phone. The app is new and they have a note about it not syncing changes made on the website to the phone yet and either by design or evil plotting there was no way to export the contacts.



My vocation to the rescue! They were using the prototype.js library to run the app and after some digging around I found the data store.
TMO.ABPORTAL.ABIHM.ContactManager is the object that manages the contacts' actions and the _datas property is an array of contact javascript objects. So in the firebug console I wrote some code to get the contacts and wrote a csv file to an empty div. I then took that div into Wordpad to get the lines to break correctly on Windows and did an import into Windows Address Book. The rest is history!



Here's the code I used:



var data = ["firstname,lastname,name,homeMobile,homePhone1,homePhone2,workMobile,workPhone1,workPhone2"];
TMO.ABPORTAL.ABIHM.contactManager._datas.each(function(person) {
var a = [];
a.push(person.firstname);
a.push(person.lastname);
a.push(person.name);
a.push(person.homeMobile);
a.push(person.homePhone1);
a.push(person.homePhone2);
a.push(person.workMobile);
a.push(person.workPhone1);
a.push(person.workPhone2);
data.push(a.join(","));
});
$('L_footer_pane').update(data.join('\r\n'));


Monday, January 21, 2008

HTML as a programming language

I read an article a couple days ago about robots that were programmed by genetic algorithms where one of the patterns that evolved was that of a liar. I've been looking for something to try out with genetic algorithms and thought it would be interesting to see if I could create a liar bot as well.
Since I've been reading Programming Collective Intellegence (along with everyone else!) and Dave always telling me this stuff needs to be done as a tree ("LISP, NICK! LISP!") I started thinking down that path.
Then I realized that HTML is a tree, and quickly coded up this useless calculating proof of concept: HTML programming!

<body>
<div class="add">
<div class="power">
<div>x</div>
<div>2</div>
</div>
<div class="multiply">
<div>5</div>
<<div>x</div>
</div>
<div>4</div>
</div>
</body>

This is the "Code". It's a polynomial, x^2+5x+4. And then the "interpreter":

function writeExpression(action, actors) {
//console.debug(action,actors);
if (action == 'add') action = '+';
if (action == 'subtract') action = '-';
if (action == 'multiply') action = '*';
if (action == 'power') action = 'Math.pow(';

var openParen = action.indexOf("(");
if (openParen > -1) {
action += actors.join(",")+")";
return action;
} else {
return actors.join(action);
}
}

function depthFirst(el) {
if (el.childElements().length == 0) return el.innerHTML;
var children = [];
for(var i = 0; i < el.childElements().length; i++) {
children.push(depthFirst(el.childElements()[i]));
}

var expression = writeExpression(el.className, children);
//console.log(expression);
return expression;
}

function parse() {
var code = depthFirst($(document.body));
$(document.body).insert("<br/>"+code);
x = prompt('X = ?');
eval("fun = function(x) {return "+code+";}; alert('f(x) = "+code+"\\nf("+x+") = '+fun(x));");
}

It's just a depth first search that then decodes the class name into an operator and returns the equation for that branch.

Thursday, November 29, 2007

Prototype/Javascript rules

I was doing some work with the new prototype this week to display some tables that represent a part of the file system. Since each one of them was a folder and could have numerous files I needed each one to collapse, but I wanted to keep all the info in the same table so divs where out.
This isn't ground breaking, but it shows the power of the prototype.js 1.6. This code closed each row after the header row and I didn't need to provide unique id's for each row on each table! All I did as you'll see below is pass the link that was toggling the collapse and expansion.

function _toggle(a) {
a = $(a);
var trs = a.up('tbody').childElements();
trs.without(trs.first()).invoke('toggle');
a.update(a.innerHTML == "-"?"+":"-");
return false;
}
Event.observe(window, 'load', function() {
$$('a[rel="toggle"]').each(function(a) { _toggle(a);});
});

The table would be rendered something like this. You can see the toggling link. I added a "rel" attribute to be able to identify and collapse all the tables when the page loaded.

<table>
<tbody>
<tr>
<td class="name" colspan="2">
<div><a href="#" onclick="_toggle(this); return false;" rel="toggle">-</a></div>Template Something
</td>
</tr>
</tbody>
</table>

So little code that does so much. But it really isn't that much. It's just that doing this the old way required you to put in so much code with id parsing to get it done. So really it's just the right about of code for the perceived work. I like it!