This is a blog about Joose and my other mostly JavaScript-related projects. The official Joose homepage is located at Google Code.
Tuesday, October 13, 2009
Joose moves to GitHub
The official Joose repo has been moved to GitHub (Thanks to Nickolay for the work). Looking forward to your code!
Wednesday, September 30, 2009
A DSL for generating HTML with JS
Maybe some people find this interesting. I created a little DSL to generate HTML with JavaScript. Here is an example:
Yes, I know, with is very evil but it is cool in this situation.
Here is the full source. I hacked it up in 30 minutes and it is in bad need for a cleanup, but otherwise it seems to work alright.
var things = [{text: "Hello"}, {text: "World"}];
with(HTML) {
var html = div({
id: "foo",
content: a({
href: "#",
content: ["test", span("bar")]
})
}) +
div({
className: "baz",
content: map(things, function (thing) {
return p(thing.text)
})
});
alert(html)
document.write(html)
}Yes, I know, with is very evil but it is cool in this situation.
Here is the full source. I hacked it up in 30 minutes and it is in bad need for a cleanup, but otherwise it seems to work alright.
var HTML = (function () {
function encode(text) {
text = text.replace(/&/g, "&", "g");
text = text.replace(/</g, "<", "g");
text = text.replace(/>/g, ">", "g");
text = text.replace(/"/g, """, "g");
text = text.replace(/'/g, "'", "g");
return text;
}
function renderAttr(attr) {
if(!attr) return '';
var html = '';
for(var name in attr) {
var value = attr[name];
if(name === "className") name == "class";
if(name === "content") continue;
html += ' '+name+'="'+encode(value)+'"'
}
html.encoded = true;
return html
}
function makeTag (name) {
return function (paras, content) {
if(arguments.length < 2) {
content = [];
}
if(typeof content === "string") content = [content]
var attr = {};
if(typeof paras === "string") {
content = [encode(paras)];
} else if(paras == null) {
content = [];
} else if(paras.content) {
var c = paras.content;
delete paras.content;
return arguments.callee(paras, c);
} else if(paras.length > 0) {
content = paras;
} else {
attr = paras;
}
var empty = content.length === 0 ? true : false;
var html = '<'+name+renderAttr(attr)+(empty ? '/' : '')+'>';
if(!empty) {
html += content.join("");
html += ''+name+'>';
}
return html;
}
}
function map(enumerable, fn) {
var result = [];
for(var i = 0, len = enumerable.length; i < len; ++i) {
result.push(fn(enumerable[i]))
}
return result;
}
var tags = ["div", "a", "p", "span"]
var HTML = {
map: map,
encode: encode
};
map(tags, function (name) {
HTML[name] = makeTag(name)
});
return HTML;
})();
Joose IRC Channel
Wednesday, August 26, 2009
Running the Bespin command line from the, well, the command line
I felt a little masochistic today which left two possibilities open:
The following script will execute it's command line arguments as commands inside bespin (if it is running in the current tab of Safari).
Wrap this in a little shell script:
(Don't ask about line two (it is part of the masochism experience :))
... and now stuff like this works:
- fix IE6 bugs in (pick any project)
- program in AppleScript
The following script will execute it's command line arguments as commands inside bespin (if it is running in the current tab of Safari).
on run argv
tell application "Safari"
set docs to every document
set cmd to ""
repeat with c in argv
set cmd to cmd & c & " "
end repeat
set js to "(function () {if(typeof bespin != 'undefined') { return bespin.get('commandLine').executeCommand('" & cmd & "').output.replace(/
]*>/g, '\\n').replace(/<[^>]*>/g, '') } else { return '' }})()"
set out to ""
repeat with doc in docs
set output to do JavaScript js in doc
set out to out & "
" & output
end repeat
out
end tell
end run
Wrap this in a little shell script:
#!/bin/bash
cp bespin.scpt bespin.work.scpt
osascript bespin.work.scpt "$@"
(Don't ask about line two (it is part of the masochism experience :))
... and now stuff like this works:
-bash-3.2$ ./bespin set | grep collab
collaborate = off
Thursday, August 13, 2009
Bringing the awesome JSConf to Europe
@janl, @hblank and @me are proud to announce that we will bring JSConf to Europe!
From the announcement:
I'm really looking forward to the event. See you there!
From the announcement:
JSConf in Washington, DC in April this year proved to be the homecoming of a JavaScript community that didn't know it existed. The conference got top marks all around for content, community and fun. With JSConf.eu, we let that spirit live on and give JavaScript a home in Europe. (why let the americans have all the fun? :)
Mark November 7th/8th in your calendar, we'll be presenting top speakers in the field and a relaxing atmosphere in Berlin, Germany's pulsing capital. Join us for a two-day, community-focussed indie conference with top technical content around your favourite language and great opportunities to meet like-minded people.
Our speakers so far include:
Amy Hoy,
Thomas Fuchs,
John Resig,
Dion Almaer &
Ben Galbraith
I'm really looking forward to the event. See you there!
Sunday, August 2, 2009
Joose 2.1 released
We are proud to announce the release of Joose 2.1
This release is a pure maintenance release with minor fixes and enhancements:
This release is a pure maintenance release with minor fixes and enhancements:
- Fix a rare issue that occurs with Firefox 3.5 native JSON supports when using Joose.Storage
- Fix an issue with the Google Gears detection code in Joose.Gears when Gears is installed but disabled in Firefox 3.5
- Various performance enhancements in heavy used methods
- Joose.Singleton's singletonInitialize methods now receives the parameters which are passed to the first call of getInstance().
Wednesday, July 22, 2009
Google Chrome's Very Incomplete Web Worker Support
In bespin we use a facade that allows us running JavaScript code in Web Workers, Gears Workers and if those are not available in the main thread.
Google Chrome does not yet support Web Workers but since it has Google Gears built in it should use the appropriate fallback. Turns out it didn't with our original code.
I naively implemented object detection to check for the availability of the Worker-object like this:
I then tried to instantiate the Worker object. All this does is to throw an exception with the message "Worker is not enabled". This looks like an unfinished implementation that was only partially removed or something in that direction.
This code handles the special case:
Google Chrome does not yet support Web Workers but since it has Google Gears built in it should use the appropriate fallback. Turns out it didn't with our original code.
I naively implemented object detection to check for the availability of the Worker-object like this:
if (typeof Worker == "undefined") {For some reason the statement above is actually true in Chrome 2, even though as stated above support for the Worker API has not been implemented.I then tried to instantiate the Worker object. All this does is to throw an exception with the message "Worker is not enabled". This looks like an unfinished implementation that was only partially removed or something in that direction.
This code handles the special case:
var noWorker = typeof Worker == "undefined" ? true : false;I'd be very interested why this fragment of the worker implementation was left in the code? Most likely it is a bug but it is questionable whether it will be fixed since the next version of Chrome will actually support the Worker API.
if(!noWorker) {
try { new Worker("test.js") }
catch(e) {
e = e + ""
if(e.indexOf("Worker is not enabled") != -1) {
noWorker = true;
}
}
}
Subscribe to:
Posts (Atom)
