Blog
May 20th, 2008
There's been an interesting security adjustment in Firefox 3 that'll have some, potential, ramifications in some (file://-hosted) web pages. Specifically how local files are referenced and accessed, in parent directories, has changed.
For example, previously you could create an HTML page and have it request a file in a parent directory, like so:
<html>
<head>
<title>Local File
</title>
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "../some/file.txt", true);
// ... handle the response ...
xhr.send(null);
</script>
</head>
<body></body>
</html>
However that is no longer possible (just to emphasize: This is no longer possible only on locally downloaded web pages, running in file://...) as an HTML page can no longer access files in parent directories. This includes both ../ relative URLs and file://... absolute URLs.
There's a detailed discussion in the bug ticket concerning this change. Primarily it boils down to the fact that:
Users frequently download HTML pages for a variety of reasons, HTML pages have full access to the hard drive and the ability to do cross-domain communication, this combination leads to an unsuspecting mess where malicious pages can actively try to steal user information.
This change is two-fold: It's possibly frustrating (there's bound to be some HTML page somewhere that uses XMLHttpRequest to local in local information, located above the current directory) and unavoidable (having this security concern left in place would lead to undesired situations, if they haven't already).
Generally speaking I don't think this change will affect many people - but it's just something that you should be aware of, when planning your sites for Firefox 3.
UPDATE: In the original post I interpreted the Bugzilla bug as being that ALL attempts to access parent-directory files were blocked when, in fact, only items bound by the same-origin policy are (like XMLHttpRequest). This should affect significantly few pages but it's good to be aware of.
Tags: javascript, firefox, mozilla, html, security
23 Comments on 'Tightened Local File Security'
May 15th, 2008
There's been a lot of interest in yesterday's release of Google Doctype. The primary focus of the release is on documentation (specifically "documenting the Open Web") however there's also two extra, hidden, additions: A Google-released JavaScript library and an Open Web test suite. Let's break down the parts of this release.
Documentation
On the main Google Doctype site they provide a link to Browse Google Doctype which takes you to a JavaScript-laden site through which you can read the various articles that they provide. If, instead, you'd prefer to read something a little more static (and sanely linkable, bookmarkable) you can just go straight for the Google Doctype Wiki instead.
The documentation falls into 2 realms:
DOM and CSS
These are sort of API references to all the DOM and CSS properties. However, browsing through, they don't seem to be terribly useful. At best, these references are programmatically generated (seeded with initial values). It's not completely clear what its setting out to achieve but my guess is something like "if we put all the information in a wiki, maybe people will come and fill it out," which seems a little awkward (especially since it's already been done before).
The primary original content provided by this reference is related to the 'browser compatibility' section of each item. For example, examine the background-postition CSS property page. There's a whole bunch of information being tested for - and a whole lot of 'N's in the columns - in fact there's even a couple rows that contain nothing but 'N's. This says to me a couple things:
- When every browser fails a test then you're probably testing the wrong thing.
- The fact that the actual return values aren't shown makes this extra frustrating (every browser fails background-position: left - but what do they fail with? what are they returning, instead?).
- There doesn't seem to be any attempt to test for compliance. Overwhelmingly the test values appear to be "the value that goes in should be the value that comes out" - which is rarely the case. Granted, it's much easier to write tests of this nature (just generate them programmatically) but the end result doesn't really help anyone.
How-To Guides
The final portion of the documentation centers around a number of articles relating to JavaScript/DOM programming.
A number of these articles are quite good (such as the Web Security section and a couple of the other articles). However, the rest of the articles are quite... confusing. They appear to be documentation for methods of a Google JavaScript library, however they're presented as Copy-and-Paste examples that developers can use. I think most developers will be quite disappointed when they find out that it's not possible.
On the article pages the Google JavaScript library is never mentioned, nor linked to. You can eventually find it if you go to source, browse the SVN (to the right directory), and download the individual files of the library.
I think I can safely say that this is the first time that documentation for a JavaScript library has been released before the library itself.
Google JavaScript Library
The second portion of the Google Doctype release was the public unveiling of the (for lack of a better name) "Google JavaScript Library." It, currently, only existing in Google SVN. There doesn't appear to be an API reference, either - beyond the various articles provided in the above How-Tos.
Digging through the code there appears to be a huge depth of coverage for some... rather obscure JavaScript topics. If anything has been shown during the last couple years of JavaScript library development (in that the functionality that users have been asking for, and using) is that DOM traversing, DOM manipulation, Events, Ajax, and Animations are fundamental. While the Google JavaScript library does provide some DOM manipulation and Events they completely ignore all other aspects of JavaScript development. Instead they delve off into the land of object traversal, string manipulation, math helpers, and data structures.
If I had to pick a library that this one was closest to I'd have to say MochiKit. I wasn't very surprised then to find out that the Google JavaScript library's DOM helpers were heavily inspired by MochiKit.
No offense to MochiKit or the Google JavaScript library but if past history is any indicator - developers are not clamoring for another MochiKit.
Open Web Tests
The final portion of this release is related to the programmatically-generated Open Web API reference. This is a full suite of tests that cover HTML elements, JavaScript/DOM methods, and CSS properties.
Thankfully raw dumps of the results are provided for each browser so we can use this as an opportunity to see what tests are being performed (and how the results compare).
Taking a look at the JavaScript/DOM results for Firefox 3 we see a lot of 'existence' tests. The vast majority of the tests appear to be checking to see if particular methods, or properties, exist. Scroll through we see some puzzling error messages:
3. document/document-attachEvent-typeof-test.html:testTypeOf failed
"[DocumentAttacheventMethod] typeOf(document.attachEvent) != 'undefined'"
Expected not to be <undefined> (String)
Firefox 3 is failing this test because it doesn't have Internet Explorer's proprietary attachEvent method? If you continue through the results you'll see similar indicators all throughout. If you were to open Internet Explorer's results you would see a number of fails for Netscape-specific methods/properties.
Opening up the HTML Firefox 3 results we see a similar situation. In this case the HTML tests appear to focus on the availability of attribute expandos on DOM elements. For example, here's one failing test from Firefox 3:
293. attributes/ilayer-above-reflection-test.html:testReflection failed
"[IlayerAboveAttribute] ilayer.above reflects <ilayer above="foo">"
Expected <foo> (String) but was <undefined>
The ilayer element was a Netscape-specific HTML extension. Testing for its DOM compliance (and, by extension, its existence) seems quite futile.
If I had to guess as to how these tests were generated I'd say "open up a browser, spider every DOM property (or HTML attribute), and turn those into existence tests."
This raises an important point: This suite is not built for any sort of standards compliance - at all - it's simply designed to check for compatibility between browsers. Looking at this suite as a compatibility suite we can start to see some use - but it's still terribly limited (only checking for existence is hardly a good-enough indicator of a browser's proper support of a property or method).
If there's one over-arching theme to the Google Doctype release it's been "whatever we can generate automatically, or release with the least amount of fuss, let's do that, no matter how simple it may be." I'm definitely looking forward to when a full release comes along, but this doesn't appear to be it.
Tags: html, css, google, documentation, javascript, library
35 Comments on 'Google Doctype'
May 5th, 2008
Recently I was having a little bit of fun and decided to go about writing a pure JavaScript HTML parser. Some might remember my one project, env.js, which ported the native browser JavaScript features to the server-side (powered by Rhino). One thing that was lacking from that project was an HTML parser (it parsed strict XML only).
I've been toying with the ability to port env.js to other platforms (Spidermonkey derivatives and the ECMAScript 4 Reference Implementation) and if I were to do so I would need an HTML parser. Because of this fact it became easiest to just write an HTML parser in pure JavaScript.
I did some digging to see what people had previously built, but the landscape was pretty bleak. The only one that I could find was one made by Erik Arvidsson - a simple SAX-style HTML parser. Considering that this contained only the most basic parsing - and none of the actual, complicated, HTML logic there was still a lot of work left to be done.
(I also contemplated porting the HTML 5 parser, wholesale, but that seemed like a herculean effort.)
However, the result is one that I'm quite pleased with. It won't match the compliance of html5lib, nor the speed of a pure XML parser, but it's able to get the job done with little fuss - while still being highly portable.
htmlparser.js:
4 Libraries in One!
There were four pieces of functionality that I wanted to implement with this library:
A SAX-style API
Handles tag, text, and comments with callbacks. For example, let's say you wanted to implement a simple HTML to XML serialization scheme - you could do so using the following:
var results =
"";
HTMLParser("<p id=test>hello <i>world", {
start: function( tag, attrs, unary ) {
results += "<" + tag;
for ( var i = 0; i < attrs.length; i++ )
results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
results += (unary ? "/" : "") + ">";
},
end: function( tag ) {
results += "</" + tag + ">";
},
chars: function( text ) {
results += text;
},
comment: function( text ) {
results += "<!--" + text + "-->";
}
});
results == '<p id="test">hello <i>world</i></p>"
XML Serializer
Now, there's no need to worry about implementing the above, since it's included directly in the library, as well. Just feed in HTML and it spits back an XML string.
var results = HTMLtoXML("<p>Data: <input disabled>")
results == '<p>Data: <input disabled="disabled"/></p>'
DOM Builder
If you're using the HTML parser to inject into an existing DOM document (or within an existing DOM element) then htmlparser.js provides a simple method for handling that:
// The following is appended into the document body
HTMLtoDOM
("<p>Hello <b>World", document
)
// The follow is appended into the specified element
HTMLtoDOM("<p>Hello <b>World", document.getElementById("test"))
DOM Document Creator
This is a more-advanced version of the DOM builder - it includes logic for handling the overall structure of a web page, returning a new DOM document.
A couple points are enforced by this method:
- There will always be a html, head, body, and title element.
- There will only be one html, head, body, and title element (if the user specifies more, then will be moved to the appropriate locations and merged).
- link and base elements are forced into the head.
You would use the method like so:
var dom = HTMLtoDOM("<p>Data: <input disabled>");
dom.getElementsByTagName("body").length == 1
dom.getElementsByTagName("p").length == 1
While this library doesn't cover the full gamut of possible weirdness that HTML provides, it does handle a lot of the most obvious stuff. All of the following are accounted for:
- Unclosed Tags:
HTMLtoXML("<p><b>Hello") == '<p><b>Hello</b></p>'
- Empty Elements:
HTMLtoXML("<img src=test.jpg>") == '<img src="test.jpg"/>'
- Block vs. Inline Elements:
HTMLtoXML("<b>Hello <p>John") == '<b>Hello </b><p>John</p>'
- Self-closing Elements:
HTMLtoXML("<p>Hello<p>World") == '<p>Hello</p><p>World</p>'
- Attributes Without Values:
HTMLtoXML("<input disabled>") == '<input disabled="disabled"/>'
Note: It does not take into account where in the document an element should exist. Right now you can put block elements in a head or th inside a p and it'll happily accept them. It's not entirely clear how the logic should work for those, but it's something that I'm open to exploring.
You can test a lot of this out in the live demo.
While I doubt this will cover all weird HTML cases - it should handle most of the obvious ones - at least making HTML parsing in JavaScript feasible.
Tags: rhino, html, javascript, parsing
35 Comments on 'Pure JavaScript HTML Parser'
February 20th, 2008
When doing DOM-based performance testing you frequently need to pick a sample HTML document to work against. This raises the question: What is a good, representative, HTML document?
For many people a good document seems to file into one of two categories:
- A large web page with a lot of content. When we did our initial performance testing with jQuery we used Shakespeare's As You Like It (lots of elements, but a very flat structure) - Mootools uses an old draft of the W3C CSS3 Selectors recommendation. This has a lot of content, as well - thousands of elements with a medium depth structure.
- A popular web page. Common recommendations include 'yahoo.com' and 'microsoft.com'.
What's troubling is that there doesn't really seem to be any way to determine what a representative web page actually is. There's a couple things that I'd like to propose as being good indicators:
- Standards-based semantic markup (including strong use of attributes: id, class, etc.).
- Non-trivial file size and element count (testing the scalability of the performance).
- Some use of tables and form elements (frequent inclusions in most web pages).
- Strong use of CSS (frequently implies a deep element structure, in order to accommodate complex layouts).
- Pervasive use of JavaScript. If JavaScript performance analysis is being done it's probably good to start with a page that already has a desire to use it.
I think, out of all of these aspects, one page stands out: CNN.com. Here's why:
- It uses semantic HTML 4 markup with a lot of classnames and ids.
- It's about 92kb in size and has 1648 elements in it.
- It has some tables (seemingly for legacy material) and some forms (search forms, drop-downs).
- Lots of CSS and JavaScript. Makes good use of Prototype which, at least, should show an desire in having a page with performant JavaScript.
- It's, also, imperfect. I would consider this to be desirable. Rarely are pages completely without fault - and the heavy use of embedded JavaScript, ads, and non-semantic tables helps to add a stark dash of reality.
Of course, analysis could always be done against multiple pages and be viewed in aggregate but we need a place to start. So, what do you think; is CNN a good, representative, page for doing performance analysis against?
Tags: javascript, css, html, performance
12 Comments on 'A Typical HTML Page'
May 1st, 2006
So, I decided to give my site a quick redesign for the May 1st CSS Reboot. It should be noted that I’m not a web designer, but just a geeky programmer with a thing for standards-based design. I hope you enjoy my entry and my work.
When planning out the redesign of my site, I wanted to emphasize my different interests, without having a typical ‘boring’ blog and/or link list.
To do this, I grouped together all of my blog posts and links, sorted by date, then figured out when I had ‘spurts’ of interest in something. For example, I might be interested in Ruby for a couple days – but then may not revisit it for a couple weeks (which I attempt to emphasize on my site).
I also saw this as a great opportunity to show the power of the Javscript-enhanced Canvas element to draw my main pie chart. So no, that isn’t a gif or flash, it’s Javascript.
I also wanted to really emphasize the projects that I’m working on. I did this by adding a piece of constant navigation (in the right-hand sidebar) which always points to them.
So, I hope you like the new design – I’m fairly pleased with it. Some of the fonts in the blog posts could use some work, but other than that – I think it’s fine.
Happy Rebooting!
Tags: css, design, web, xhtml, html, reboot, cssreboot
5 Comments on 'Reboot!'
December 13th, 2005
Lately, I've been doing a lot of work building a parser for both XPath and CSS 3 - and I was amazed at just how similar they are, in some respects - but wholly different in others. For example, CSS is completely tuned to be used with HTML, with the use of #id (to get something by ID) and .class (to get something by its class). On the other hand, XPath has to ability to traverse back up the DOM tree with .. and test for existance with foo[bar] (foo has a bar element child). The biggest thing to realize is that CSS Selectors are, typically, very short - but woefully underpowered, when compared to XPath.
I thought it would be worth some merit to do a side-by-side comparison of the different syntaxes of the two selectors.
| Goal |
CSS 3 |
XPath |
| All Elements |
* |
//* |
| All P Elements |
p |
//p |
| All Child Elements |
p > * |
//p/* |
| Element By ID |
#foo |
//*[@id='foo'] |
| Element By Class |
.foo |
//*[contains(@class,'foo')] 1 |
| Element With Attribute |
*[title] |
//*[@title] |
| First Child of All P |
p > *:first-child |
//p/*[0] |
| All P with an A child |
Not possible |
//p[a] |
| Next Element |
p + * |
//p/following-sibling::*[0] |
Syntactically, I was surprised how similar the two selectors were, in some cases - especially between the '>' and '/' tokens. While they don't always mean the same thing (depending on what axis you're using in XPath), they're generally assumed to mean the child element of the parent. Also, the ' ' (space) and '//' both mean 'all descendants of the current element'. Finally, the '*' means 'all elements', regardless of their name, in both.
Even though I already knew all of this ahead of time - it's certainly nice being able to rediscover the similarities when it comes down actually having to program an implementation of them.
1 This isn't right due to the fact that it would match 'foobar' and 'foo bar', when only the second pattern is correct. The actual syntax would be far more complex and would probably require multiple expressions to get the job done.
Tags: xml, xpath, css, dom, html
10 Comments on 'XPath and CSS Selectors'
August 22nd, 2005
Ever since the Behaviour code was released, some time ago, my mind has been churning this powerful topic over. The premise for the module is as follows: Using the power of Pseudo-CSS Selectors, bind your Javascript functions to various HTML elements in the DOM. Looking at how Behaviour works, I've never been completely happy - it simply seems too tedious and verbose for everyday use. I've since begun to tinker with different styles of code layout - trying to find an optimal solution. Some of my biggest gripes with Behaviour are:
- You can't do any heirarchical selectors. For example, binding to "#foo bar" and "#foo bar .baz" fall under two completely different statements. It seems as if this could/should be streamlined.
- The Behaviour object doesn't provide any sort of binding-enhancers to make attaching to an event (e.g. "click") easier to do.
- The resulting Behaviour code is simply too verbose and too ugly - there is an excess of characters/formatting which will probably scare off a casual Javascript programmer.
I've created a syntactical mock-up for how I think 'Behaviour' could've been implemented. I'm not sure if I'm completely happy with it yet - the only way to know is to do some real-world testing and come back with some tweaks.
Sample #1
Note: In all of these examples, Behaviour uses 'element.onclick' (or similar bindings) in order to attach an event handler - this is generally accepted as an improper way of doing this, since you will only be able to attach one event handler at a time - newer handlers will overwrite older ones.
Behaviour.register({
'#example li': function(e){
e.onclick = function(){
this.parentNode.removeChild(this);
}
}
});
The same as above, done in my code:
$('#example li').bind('click',function(){
this.parentNode.removeChild(this);
});
Syntactic fluff comparision (This is a comparision of how many extra non-critical characters there are, slowing the programmer down - not counting endlines/whitespace):
A: Behaviour.register({'':function(e){e.on=}});
B: $('').bind('',);
Sample #2
This is the second example made available on the Behaviour web site. It goes to two disparate branches in the DOM Document and attaches two different event handlers.
Behaviour.register({
'b.someclass' : function(e){
e.onclick = function(){
alert(this.innerHTML);
}
},
'#someid u' : function(e){
e.onmouseover = function(){
this.innerHTML = "BLAH!";
}
}
});
The same as above, done using my syntax:
$
('b.someclass').
bind('click',
function(){
alert(this.
innerHTML);
});
$('#someid u').bind('mouseover',function(){
this.innerHTML = 'BLAH!';
});
Syntactic fluff comparision
A: Behaviour.register({'':function(e){e.on=},'':function(e){e.on=}});
B: $('').bind('',);$('').bind('',);
Sample #3
This is the Behaviour code required to meet a 'more advanced' test case. I included changing style properties and element attributes.
Behaviour.register({
'#foo ol li': function(a) {
a.title = "List Items!";
a.onclick = function(){alert('Hello!');};
},
'#foo ol li.tmp': function(a) {
a.style.color = 'white';
},
'#foo ol li.tmp .foo': function(a) {
a.style.background = 'red';
}
});
And the same result using my syntax:
$('#foo ol li')
.set('title','List Items!')
.bind('click',function(){alert('Hello!');})
.select('.tmp')
.style('color','white')
.select('.foo')
.style('background','red');
Syntactic fluff comparision For this comparision I included the selectors that Behaviour uses, but shouldn't need to.
A: Behaviour.register({'':function(a){a.=;a.on=;},'#foo ol li':function(a){a.style.='';},'#foo ol li.tmp':function(a){a.style.='';}});
B: $('').set('','').bind('',).select('').style('','').select('').style('','');
I'm going to have some more information on, how exactly, this new method of binding would work - hopefully along with some demoable code. More coming very soon!
Tags: javascript, css, html, programming
3 Comments on 'Selectors in Javascript'
August 8th, 2005
I'm looking for a Javascript/Design Guru to help get some applications off the ground.
If you can look at Prototype (http://prototype.conio.net/) and say "That's cool, but I can do better!", or you can scoff at the designs on Stylegala (http://stylegala.com/) and CSS Vault (http://cssvault.com/) - then this job is for you!
Knowledge of the following is a must:
- Advanced Object Oriented Javascript
- Ajax (Asynchronous Javascript and XML)
- XHTML
- Advanced, Modern, Design Capabilities
- Advanced CSS
Big Plus:
- Adobe Illustrator
- Knowledge of Microformats
- Knowldge of Social Networks
If you are primarily Javascript OR Design-Oriented - let me know, as I may still have some work for you.
This job will be on a part-time/contract basis - most likely telecommuting. Pay will determined by your skill level and previous experience.
Apply for this Job Here OR email me.
Tags: illustrator, html, xml, xhtml, design, css, jobs, ajax, javascript, adobe
17 Comments on 'Wanted: Javascript/Design Guru'
·
« Previous entries