Re: Namespace-aware APIs do not need to suck

On Thu, 19 Nov 2009 10:09:45 -0500, Julian Reschke <julian.reschke@gmx.de>  
wrote:

> Michael A. Puls II wrote:
>> ...
>> I tried the following with Opera:
>>  (function() {
>>     var oldCreateElement = Document.prototype.createElement;
>>     Document.prototype.createElement = function() {
>>         var args = arguments;
>>         if (args.length !== 1 && args.length !== 2)
>>             throw new Error("WRONG_ARGUMENTS_ERR");
>>         if (args.length === 2)
>>             return this.createElementNS(args[0], args[1]);
>>         var pattern = /^\{(.+)\}(.+)$/g;
>>         var ref = this;
>>         var el = null;
>>         args[0].replace(pattern, function(match, ns, name) {
>>             el = ref.createElementNS(ns, name);
>>         });
>>         return el !== null ? el : oldCreateElement.call(this, args[0]);
>>     };
>> })();
>> var x = document.createElement("{http://www.w3.org/1999/xhtml}div");
>> var y = document.createElement("http://www.w3.org/1999/xhtml", "div");
>> var z = document.createElement("div");
>> alert(x);
>> alert(y);
>> alert(z);
>>  Using the first way seems pretty cool by me fwiw.
>> ...
>
> Very cool.

A correction for "{}div":

(function() {
     var oldCreateElement = Document.prototype.createElement;
     Document.prototype.createElement = function() {
         var args = arguments;
         if (args.length !== 1 && args.length !== 2)
             throw new Error("WRONG_ARGUMENTS_ERR");
         if (args.length === 2)
             return this.createElementNS(args[0], args[1]);
         var el = null;
         var ref = this;
         args[0].replace(/^\{(.*)\}(.+)$/, function(match, ns, name) {
             if (ns === "")
                 el = oldCreateElement.call(ref, name);
             else
                 el = ref.createElementNS(ns, name);
         });
         return el !== null ? el : oldCreateElement.call(this, args[0]);
     };
})();
var x = document.createElement("{http://www.w3.org/1999/xhtml}div");
var y = document.createElement("http://www.w3.org/1999/xhtml", "div");
var z = document.createElement("div");
var a = document.createElement("{}div");
alert(x);
alert(y);
alert(z);
alert(a);

(use HTMLDocument for both spots if you want that to work in Firefox)

Other functions like getElementsByTagName, getAttributeNS and  
createAttributeNS could work the same way where you use "{ns}name", or  
separate args for ns and name, or just 'name' for the default namespace.

Then, if the ua wants to store everything internally as "{ns}name", the NS  
functions could make sure to create "{ns}name" from the separate ns and  
name args before doing creation or lookup. And, in the non-NS functions,  
if they got the "{ns}name" form, they'd do the creation/lookup directly  
instead of splitting it apart into 2 arguments only to have the NS  
function put it back together before doing the creation/lookup (as an  
optimization). Something like that anyway.

-- 
Michael

Received on Friday, 20 November 2009 11:26:00 UTC