extending the web is hard

The Prototype library defines a .replace() method on any element that replaces the contents of that element. The WebForms 2 spec defines a .replace attribute on INPUT type=submit that can be set to replace="values" to make a form submit not replace the entire document but simply update the form contents. You can't give two different things the same name. So if you use Prototype and call someInput.replace() your script will stop with an error in Opera because we support WebForms2 and "replace" is a property and not a method.

The wonderful flexibility of ECMAScript / JavaScript lets script authors define nearly anything and everything just about anywhere in the environment. That's why extending JavaScript is getting so complicated – anything we add to specifications and in browsers risks conflicting with something that an author already added somewhere. ES4 plans to come to the rescue with namespaces but until we get there we'll keep stumbling into problems when we try to improve the web. HTML5, you're overdue and welcome – but proceed with caution..

Advertisements

8 thoughts on “extending the web is hard

  1. I bugged this a while ago at prototype. It just became a documentation task though. Also prototype clashes with more elements than just the input type=submit last i checked:

    HTMLButtonElement.replace
    HTMLFormElement.replace
    HTMLInputElement.replace
    HTMLTextAreaElement.wrap

    ES4 plans to come to the rescue with namespaces but until we get there we'll keep stumbling into problems when we try to improve the web

    I will be happy to see Opera move beyond js version 1.5.

  2. I will be happy to see Opera move beyond js version 1.5.

    Me too! These sorts of problems demonstrate why we need ES4 namespaces.

  3. Prototype needs to just give up this rude behavior, created a major release that's not backwards compatible, and be done with it. They can't cooperate with other libraries, and now they're breaking browsers. Sheese!

  4. So if you use Prototype and call someInput.replace() your script will stop with an error in Opera because we support WebForms2 and "replace" is a property and not a method.

    But if Opera sees that a method is called instead of a property (thanks to the parentheses), why does it return an error instead of looking for that particular method?

  5. @scipio: In javascript, functions are first-class objects. I.e. a function is a "callable" property. So you can "grab" a function as a property and execute it later, like so:

    fn = obj.prop;
    fn.call(obj);

    So it's not exactly in the intent of javascript to differentiate between methods and properties.The problem with replacing "replace" is probably that any function is converted to a string before it is assigned.You could "fix" this with Getters&Setters to achieve a certain behavior such as "if value passed is a string, use it for WebForms, else use it as normal property".My implementation is as follows:

    function closureMaker(scope,prop){
            var oGetr = scope.__lookupGetter__(prop);
            var oSetr = scope.__lookupSetter__(prop);
            var value, useValue;
    
            function getr(){
                if(useValue) return value;
                else return oGetr.call(this);
            };
            function setr(x){
                if(typeof x == "string") {
                   oSetr.call(this,x);
                   useValue = false;
                }
                else {
                   value = x;
                   useValue = true;
                };
            };
            scope.__defineGetter__(prop,getr);
            scope.__defineSetter__(prop,setr);
    };
    input = document.createElement('input');
    
    closureMaker(input,"replace");
    
    alert(typeof input.replace); //string
    
    input.replace = function(){};
    
    alert(typeof input.replace); //function
    
    alert(new input.replace()); //use function as constructor
    
    input.replace = "value1,value2,value3";
    
    alert(typeof input.replace); //string

    This would be a lot easier if Opera exposed the WebForms extensions (e.g. replace) on HTMLInputElement.prototype, though. A simple call like this would suffice:

    closureMaker(HTMLInputElement.prototype,"replace");
  6. This would be a lot easier if Opera exposed the WebForms extensions (e.g. replace) on HTMLInputElement.prototype

    Um, we don't?? No idea why. Do you know if there is a bug report on this?

  7. Um, we don't?? No idea why. Do you know if there is a bug report on this?

    Well, the latest build I tested here is beta2 of the 9.5 branch, but I believe Opera doesn't, no. I don't believe there is a bug report on this, either.I don't know the WF2-Interface good enough to tell, but I think it might be related to different "<input type="s having different applicable attributes. Maybe they don't (I really don't know) and this is a valid complaint.edit: Hmm. Some other properties aren't represented, either. HTMLButtonElement.prototype.type is "undefined" although it should rather be "submit" (imho, unless I'm totally silly). I filed a bug on that a while ago I believe.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s