[OpenLayers-Dev] Constructor trouble when testing new control

Christopher Schmidt crschmidt at metacarta.com
Thu Oct 11 15:24:18 EDT 2007

On Thu, Oct 11, 2007 at 08:06:37PM +0100, Ian Mayo wrote:
> I'm afraid I can't get my head around an error that's being thrown by
> my test at:
> http://trac.openlayers.org/browser/sandbox/ianmayo/openlayers/tests/Control/test_ScaleLine.html
> when I execute the following line in test_01_Control_ScaleLine_constructor:
> control = new OpenLayers.Control.ScaleLine();
> I get this error reported:
> test_01_Control_ScaleLine_constructor planned 2 assertions but got 0;
> fail 0 ok 0
> exception: : object: [Exception... "Illegal operation on WrappedNative
> prototype object" nsresult: "0x8057000c
> (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame ::
> file:///home/ian/dev/openlayers/openlayers/lib/OpenLayers/Util.js ::
> anonymous :: line 60" data: no]
> The guilty line is calling my constructor in
> http://trac.openlayers.org/browser/sandbox/ianmayo/openlayers/lib/OpenLayers/Control/ScaleLine.js:
> initialize: function(element, options) {
>    OpenLayers.Control.prototype.initialize.apply(this, arguments);
>    this.element = OpenLayers.Util.getElement(element);
> },
> I have to admit, I don't fully understand how the
> constructor/initialiser model is working.

So, there are a couple things to be aware of.

1. The Control.initialize prototype expects one argument, an object with
   key/value pairs to set on the control. Currently, you pass an element
   as the first argument, which means you pass that to your control
   prototype. You should instead do:
   OpenLayers.Control.prototype.initialize.apply(this, [options]);

   The reason this is happening is that it's attempting to copy the
   'hasOwnProperty' from an HTML DOM Element, which is not allowed on a
   "Wrapped XP Native" object (HTML DOM element). Annoying error
   message, huh?

2. In general, passing an element as part of the contorl init is not how
   we do things anymore. Instead, we use the 'this.div' property: this
   can be passed via the options as {div: HTMLDOMElement}, which means
   that we don't have to do anything special for control initializers
   (they can all have the same args) which would have saved you here.  

   We haven't updated the old code, but control.panel demonstrates it --
   but so long as you use this.div for your HTML element, you don't
   really need to do anything to take advantage of this.

Hope this helps...

Christopher Schmidt

More information about the Dev mailing list