Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6481 (closed defect: fixed)

Opened 3 years ago

Last modified 2 years ago

Object.extend problem in Firefox 2.0 RC3

Reported by: mytto Assigned to: sam
Priority: high Milestone: 1.x
Component: Prototype Version: edge
Severity: blocker Keywords: regression
Cc:

Description

For some unspeakably weird reason, there's a real problem with Object being supplemented with the extend() function when you open a new window in Firefox 2.0 RC3

You can find a simple test case test case for Object.extend bug on Mediboard SIH portal.

Just unzip the archive, open the HTML file in the browser, test Object.extend (it'll work), open the new window, test it again in the new window (it'll fail).

Hope you can find some hack around...

Attachments

Test case for Object.extend.zip (12.1 kB) - added by mytto on 10/24/06 19:05:02.
Test case
ObjectTest.html (1.1 kB) - added by lukem on 10/25/06 05:41:28.
Standalone test case

Change History

10/24/06 19:05:02 changed by mytto

  • attachment Test case for Object.extend.zip added.

Test case

(in reply to: ↑ description ) 10/25/06 05:40:05 changed by lukem

  • priority changed from normal to high.

Confirmed on FF2 final.

FF2 seems to be resetting Object; all properties added to it (not just extend) disappear. It also seems to overwrite the Function object, but not String, Number, Event, Array or Element.

https://bugzilla.mozilla.org/show_bug.cgi?id=355161 is the closest thing I can find to a dup of this in bugzilla.

10/25/06 05:41:28 changed by lukem

  • attachment ObjectTest.html added.

Standalone test case

(follow-up: ↓ 3 ) 10/25/06 08:02:31 changed by mytto

  • keywords set to regression.
  • version set to edge.

A teammate took the liberty to post a new bug (357947) in Bugzilla attaching your standalone test case. I really encourage you guys voting for both these bugs.

(in reply to: ↑ 2 ; follow-up: ↓ 4 ) 10/25/06 20:37:17 changed by lukem

In case anyone is really desperate for a workaround... you can change Object to Obj and Function to Func and then modify all the prototype.js code to manually call things like call Obj.extend(...) and Func.bind(function(){},someObj). This is really invasive of course and kind of sucks.

Here are the modified Obj and Func objects:

Obj = {
  extend: function(destination, source) {
    for (var property in source) {
      destination[property] = source[property];
    }
    return destination;
  },

  inspect: function(object) {
    try {
      if (object == undefined) return 'undefined';
      if (object == null) return 'null';
      return object.inspect ? object.inspect() : object.toString();
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Obj.extend({}, object);
  }
}

Func = {
  bind: function() {
    var args = $A(arguments), __method = args.shift(), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function(object) {
    var args = $A(arguments), __method = args.shift(), object = args.shift();
    return function(event) {
      return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
    }
  }
}

Then you have to do a ton of search and replaces like

Object.extend => Obj.extend
foo.bind(bar) => Func.bind(foo, bar)
foo.bindAsEventListener(bar) => Func.bindAsEventListener(foo, bar)

This workaround totally sucks. But it may be better than nothing. Anyone have any better ideas? :-)

(in reply to: ↑ 3 ) 10/26/06 15:02:20 changed by mytto

Replying to lukem:

In case anyone is really desperate for a workaround... you can change Object to Obj and Function to Func and then modify all the prototype.js code to manually call things like call Obj.extend(...) and Func.bind(function(){},someObj). This is really invasive of course and kind of sucks.

The issue there is to recode all prototype.js derived code also, e.g. Scriptaculous, Rico, ..., as well as your own prototypish scripts.

I have a slightly better, far less invasive workaround that seems to work (I still need further testing, but yet it runs). The overall idea is to redeclare the missing stuff just after page loading, i.e. as after body.onload event.

Here's what you should do:

1. create a javascript file like this one

/**
 * Hack for Firefox 2.0 bug
 *
 * Bug causes Object and Function object to be emptied 
 * when opening a new window
 */
 
ObjectInitialisation = {
  // Function to be launched during body.onload event
  hackIt : function() {
  
    if (Object.extend) {
      return;
    }

    Object.extend = function(destination, source) {
      for (property in source) {
        destination[property] = source[property];
      }
      return destination;
    }

    Object.inspect = function(object) {
      try {
        if (object == undefined) return 'undefined';
        if (object == null) return 'null';
        return object.inspect ? object.inspect() : object.toString();
      } catch (e) {
        if (e instanceof RangeError) return '...';
        throw e;
      }
    }
	
    ...
}

2. In the HTML file, add a body.onload handler

<body onload="ObjectInitialisation.hackIt()">
...

(follow-up: ↓ 6 ) 10/26/06 15:07:45 changed by mytto

Last remark on previous hack, you have to make explicit call to Object.extend (same for other functions) instead of inherited calls.

In deed you shouldn't use

myObj.extend(myOtherObj);

But you should rather use

Object.extend(myObj, myOtherObj);

(in reply to: ↑ 5 ; follow-up: ↓ 7 ) 10/26/06 16:33:16 changed by DavidPodolsky

Guys I also ran into this issue and made a thread on Mozillazine with some good feedback and I voted on the bug in bugzilla (357947) to fix this.

Here is the thread: http://forums.mozillazine.org/viewtopic.php?t=478945

Also here is a very simple/dirty (ok ,very dirty) workaround that I came up with. Since the bug only happens with new popups and will actually function correctly after a refresh I just stuck a window.location.relaod into into my body.onload function.

.. if(typeof Object.extend == 'undefined') { window.location.reload(); } ...

This is nice because it doesn't require any code change to the base libraries or duplicate coding.

(in reply to: ↑ 6 ; follow-up: ↓ 8 ) 10/26/06 22:27:33 changed by lukem

I had tried doing similar window.location.reload() and onload() tricks too, but (at least in my testing), the Object and Function properties were occasionally removed later on as well... like minutes after opening the window, not just in the window loading stage.

(in reply to: ↑ 7 ) 10/27/06 07:08:58 changed by mytto

Replying to DavidPodolsky:

Also here is a very simple/dirty (ok ,very dirty) workaround that I came up with. Since the bug only happens with new popups and will actually function correctly after a refresh I just stuck a window.location.relaod into into my body.onload function.

I also had thought to that even least invasive ever workaround, but that flickering rapidly turned me mad. This is not an option from my (users) perspective.

03/06/07 11:06:54 changed by bitsweat

  • status changed from new to closed.
  • resolution set to fixed.

https://bugzilla.mozilla.org/show_bug.cgi?id=355161#c29

Looks like it was fixed in Firefox 2.0.0.1