Cannot wrap 'Element''s 'addEventListener' method

On Firefox ( v2 and v3, and probably the earlier versions) it does not
seem possible, at least under some circumstances, to extend the
'addEventListener' prototype of the 'Element' object in JS or to
extend the prototype of its inheriting objects.  This forces
JavaScript frameworks that would like to leverage Element's prototype
for this (or its inheriting objects) to treat Firefox like IE in this
case -- they have to perform an extension operation on every single
individual dom element that they need framework-style behavior from.
That's a significant performance hit.

In a case where WebKit (Safari 3) works perfectly, I get either a
silent failure (property extensions of 'Element.prototype' are
successfully made, but 'addEventListener' is still the native one and
not the extended one intended by the code) or (for example when trying
to extend 'HTMLDivElement.prototype) an explicit exception ("Illegal
operation on WrappedNative prototype object").

Given this code at line 469 of https://us.etrade.com/javascript/et1/src/cor=
e/dom/Element.js

=20
if( defined( self.HTMLElement                                      )
&&
            ( !
HTMLElement.prototype.hasOwnProperty( "addEventListener"    ) &&
              !
HTMLDivElement.prototype.hasOwnProperty( "addEventListener" ) )  )  {
            Element.prep( Element.prototype );
        }

If I add a blanket pass to the conditional above like so:

   if( true || defined . . .

Then what happens is that the 'addEventListener' method acts like (and
possibly is) the original one, resulting in a loss of the intended
object context.  The JavaScript framework intends that the new
'addEventListener' method (wrapped in 'Element.js'; url above)  take
an object-context argument, but that is lost, resulting in the object
context being the dom element.

That causes an error since the expected methods are not on that
object:

FF 3 (but same on FF 2):

    Welcome to =93Venkman=94, the JavaScript debugger. Please read the FAQ
at <http://www.hacksrus.com/~ginda/venkman/faq/venkman-faq.html>.
Visit the Venkman homepage <http://www.mozilla.org/projects/venkman/>
for more information.
    You are running Venkman version 0.9.87.4.
    Use =93/help <command-name>=94 for help on specific commands.
    Visit <x-jsd:help> for a searchable command reference.
    Commands start with a forward-slash ('/') character. Any text that
DOES NOT start with a forward-slash will be evaluated as JavaScript.
For example, to execute the=93step=94 command, type =93/step=94. To evaluat=
e
=931 + 1=94, just type =931 + 1=94.
    Recorded local startup 119, global 5805809.
    Error ``this.emitEvent is not a function'' [x-] in file ``https://
lxdev6m0.etrade.com:14755/javascript/et1/src/lib/model/messenger/
request/mechanism/ScriptInclude.js'', line 135, character 0.
    Stopped for error handler.
    #0: function anonymous(p_eEvent=3DEvent:{0}) in <https://
lxdev6m0.etrade.com:14755/javascript/et1/src/lib/model/messenger/
request/mechanism/ScriptInclude.js> line 135
    133: eventLoad : function( p_eEvent ) {
    134: // Let the application know that a response has been received
from the server:
    135: this.emitEvent( p_eEvent );
    136: },
    137:
    Continuing from error handler.

Unfortunately, allowing custom js objects to listen to dom events with
methods (not plain functions) is very critical.  The only way
currently to get this on FF (and on IE) is to wrap the dom objects on
an individual basis.  Apparently, using the prototype property here is
not possible.  But as mentioned above, it works fine on WebKit (Safari
3).

When I try an alternative approach, by moving down the prototype chain
to 'HTMLDivElement' (which is a much less preferable alternative than
just extending 'Element'), doing this:

  Element.prep( HTMLDivElement.prototype );

I get this error (same on FF 3 and 2):

     Exception ``[Exception... "Illegal operation on WrappedNative
prototype object" nsresult: "0x8057000c
(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame ::
https://lxdev6m0.etrade.com:14755/javascript/et1/src/core/dom/Element.js
:: anonymous :: line 430" data: no]'' thrown from function
anonymous(p_oElement=3DXPC_WN_ModsAllowed_NoCall_Proto_JSClass:{69}) in
<https://lxdev6m0.etrade.com:14755/javascript/et1/src/core/dom/
Element.js> line 430.
     Stopped for thrown exception.
     #0: function
anonymous(p_oElement=3DXPC_WN_ModsAllowed_NoCall_Proto_JSClass:{69}) in
<https://lxdev6m0.etrade.com:14755/javascript/et1/src/core/dom/
Element.js> line 430
     428: // If not an Element/HTMLElement prototype, and 'nodeType' !
=3D 1, return here:
     429: if( !( oE =3D=3D=3D self.Element.prototype ) &&
     430: ( oE.nodeType !=3D 1 ) ) { // 'self' is used as an
optimization.
     431: oE.bPreppedByEt1 =3D true;

A complete example of this code in context may be found at:

   https://us.etrade.com/javascript/et1/dev_tools/test/harness/lazy_loader_=
inline_script/index-src.html

In sum: Is this a bug in Firefox?  It seems so.  Requesting feedback
on that point: If this is a bug, I'll report it.

Last but not least: Does anyone know of any workarounds?

Thank you in advance,

      - cb
0
christopherbalz
7/28/2008 7:11:58 PM
mozilla.dev.tech.js-engine 2054 articles. 0 followers. Post Follow

4 Replies
877 Views

Similar Articles

[PageSpeed] 37

= Edit =

a) "extend the 'addEventListener' prototype of the 'Element' object "
in the first paragraph above should read instead, "extend the
'addEventListener' method of 'Element' object's prototype"

= Clarification =

The framework operation performed on 'addEventListener' is technically
a wrap, but has the effect of extending its functionality:

                     oE.addEventListener = function( p_sEventName,
p_fnHandler, p_oContext, p_bCapture ) {
                         var fnHandler = Et1.getHandler( p_fnHandler,
p_oContext );
                         this.plainAddEventListener( p_sEventName,
fnHandler, p_bCapture );

                         return fnHandler;
                     };

In the code snippet above (from https://us.etrade.com/javascript/et1/src/core/dom/Element.js
), 'this.plainAddEventListener' is a cached version of the original,
native event listener.

0
christopherbalz
7/28/2008 10:15:27 PM
Sorry if I misunderstood your question..
Try extending Node

   Node.prototype.aaaa=1;
   document.body.aaaa; //gives 1

BTW, I think this is off-topic to this group "js-engine",
you may want to try on Web-Dev group or a DOM group
0
biju
8/1/2008 1:03:35 AM
On Jul 31, 6:03=A0pm, biju <bijumaill...@yahoo.com> wrote:
> Sorry if I misunderstood your question..
> Try extending Node
>
> =A0 =A0Node.prototype.aaaa=3D1;
> =A0 =A0document.body.aaaa; //gives 1
>
> BTW, I think this is off-topic to this group "js-engine",
> you may want to try on Web-Dev group or a DOM group

Thanks for the message.  I get properties added to 'Element.prototype'
fine -- except for 'addEventListener'.

The problem is that asymmetry.  Since 'Element.prototype' is exposed
in the js-engine, it should work like any other object.

That's why I posted here in js-engine.  However, possibly there is a
bug in the exposure of 'Element.prototype' in the DOM implementation.
Then it would be best to post in the DOM group.

If this is actually a browser bug, it would not be a WebDev issue.



0
christopherbalz
8/1/2008 4:15:26 AM
On Jul 31, 11:15=A0pm, christopherbalz
<ChristopherMB...@stanfordalumni.org> wrote:
> On Jul 31, 6:03=A0pm, biju <bijumaill...@yahoo.com> wrote:
>
> > Sorry if I misunderstood your question..
> > Try extending Node
>
> > =A0 =A0Node.prototype.aaaa=3D1;
> > =A0 =A0document.body.aaaa; //gives 1
>
> > BTW, I think this is off-topic to this group "js-engine",
> > you may want to try on Web-Dev group or a DOM group
>
> Thanks for the message. =A0I get properties added to 'Element.prototype'
> fine -- except for 'addEventListener'.

Well, let's see what we can figure out by playing with JavaScript a
little.  I'm using FF3.  Answers may vary.

  document.body.__proto__ =3D=3D=3D HTMLBodyElement.prototype
      =3D=3D=3D> true
  document.body.__proto__.__proto__ =3D=3D=3D HTMLElement.prototype
      =3D=3D=3D> true
  document.body.__proto__.__proto__.__proto__ =3D=3D=3D Element.prototype
      =3D=3D=3D> true
  document.body.__proto__.__proto__.__proto__.__proto__ =3D=3D=3D
Node.prototype
      =3D=3D=3D> true

So far so good.  Now, where does an element inherit the
addEventListener method from?

  document.body.hasOwnProperty("addEventListener")
      =3D=3D=3D> false
  HTMLBodyElement.prototype.hasOwnProperty("addEventListener")
      =3D=3D=3D> true

Hmm.  It looks like Gecko reflects interface methods on *every*
prototype that implements them.  This is bad news for anyone who wants
to hook this method.  Not all addEventListener methods are inherited
from one central place.  Instead, there is one per DOM element class.

> The problem is that asymmetry. =A0Since 'Element.prototype' is exposed
> in the js-engine, it should work like any other object.

Maybe you're right; the currently existing standards don't specify
this.

-j
0
Jason
8/13/2008 5:05:47 PM
Reply:

Similar Artilces:

''''''''''''''''''''
Name: haznen Email: haznenatyahoodotcom Product: Gran Paradiso Alpha 8 Summary: '''''''''''''''''''' Comments: '''''''''''''''''''''''''''''''''''' Browser Details: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20061204 UGES/1.7.2.0 GranParadiso/3.0a1 From URL: http://www.mozilla.org/projects/granparadiso/ Note to readers: Hendrix gives...

'''''
Name: mario Email: ramar17atfastwebnetdotit Product: Gran Paradiso Alpha 2 Summary: ''''' Comments: K: Browser Details: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a2) Gecko/20070206 GranParadiso/3.0a2 ...

'do' won't 'do' if '/'
Greetings to All from Au, Have a NetWare Perl 5.8.4 and wanted to tweak File\Spec\NW.pm to try and standardise on '/' separators. If I run a test script (t/uni/lower.t) with an unmodified NW.pm, it calls t/uni/case.pl, that, in case.pl, (when the path separators are '\'), the $file is '..\lib\unicore\To\Lower.pl' and the following code portion works, with $simple getting a returned table: sub casetest { my ($base, $spec, $func) = @_; my $file = File::Spec->catfile(File::Spec->catdir(File::Spec->updir, "lib", &qu...

'''
Name: L Lachowsky Email: e2brutus_10atyahoodotcom Product: Firefox Summary: ''' Comments: why duddn this surprise me... I change default server from IE to Mozilla, and then i get error messages. well, shud I decide to not get on my computer with Mozilla..or shud I risk security breeches with IE....hmmm at least i can get on the internet with IE Browser Details: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 From URL: http://hendrix.mozilla.org/ Note to readers: Hendrix gives no expectation of a response to this fee...

Cast from type ''''DBNull'''' to type ''''String'''' is not valid.
How do I avoid getting this error: Cast from type ''''DBNull'''' to type ''''String'''' is not valid. I am trying to get values from the database into a form for updating using a Datareader, SQL is set to allow nulls for certain fields as they are not required but the only way I can get the form to display is by adding a space in SQL. Is there another way around this? Check if it is equal to DBNull.Value first and if it is, don't do the cast.Stanley Tan theSpoke Blog Where in the code does it need to go? I am using the following and it's the profile that isn't always requi...

'or' or 'union'
Hello I was just wondering, in general what is better to use, an 'or' clause in a select or a 'union' to join two selects together. Do both statements create work tables? Many thanks Alex I think OR will be better than union. because suppose u have 3 tables and using OR u can join table a and table b and table c so each table will have only one read. but using union you will join table a and table b and in another query of union u will use table (a or b) and table c so ur one read is more in union . Ramdas Alex Cheung wrote: > Hello > >...

'IN' Clause or 'OR'
Hello, [1]: select * from TABLEA where COL1 IN('value1','value2''valu3'....) [2]:select * from TABLEA where COL1 = 'value1' OR COL1= 'value2' OR COL1='valu3'. TABLEA is a huge table and it has non-clustered index on COL1. Among the above 2 queries, which query will give me the better performance or fast response and WHY? What is the difference between 'IN' and 'OR' clauses as for as Sybase Optimization is concerned. Which is the better one to be used on huge tables. Thanks. Mac An IN list is treated ...

'b'..'a'
Hello. I'm using defferent 5.6.0's for Win32. I wonder wheter following behaviour is intentional or not: d:\>perl -e "print 'b'..'c'" bc d:\>perl -e "print 'b'..'a'" bcdefghijklmnopqrstuvwxyz I expected empty list in latter case, like in perl -e "print 'bb'..'a'" <!ENTITY Vadim REALLIFE "Vadim V.Konovalov, St.Petersburg, Russia"> &Vadim; On Wed, Sep 20, 2000 at 03:14:41PM +0400, Konovalov, Vadim wrote: > Hello. > > I'm using defferent 5.6.0'...

EXEC sp_msforeachtable 'sp_spaceused ''?'''
What does the following SQL code mean?  EXEC sp_msforeachtable 'sp_spaceused ''?'''Johan TheunissenMCPD, MCSE, MCTS BizTalk 2006==============================Please mark the most helpful reply/replies as "Answer". JohanNL:sp_msforeachtable This is the name of the SP that resides in the master database.  This SP executes one or more commands for a table. JohanNL:sp_spaceused This is the command that you want to run for each of the tables residing in your current database.  As you might have understood so far, that this is again a...

'To', 'CC', & 'BCC'
Name: Dick Tracy Email: philipdottracyatoptusnetdotcomdotau Product: Thunderbird Summary: 'To', 'CC', & 'BCC' Comments: I have just started using Thunderbird and while I find it quite excellent- I suggest having a button to add addressees to 'BCC' as well. Currently each 'BCC' addressee has to be selected manually. I send e-mail to quite a number of people at a time and I do not wish to readily spread others addresses easily. Browser Details: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0....

'Value' should be between 'minimum' and 'maximum'.
I'm attempting to invoke with parameters:  Dim thing2 As New mydelsubPBStep(AddressOf pbStep) Me.Invoke(thing2, "setMax", dt.Rows.Count)      <---- this is where the error occurs   the delegate looks like this: Private Delegate Sub mydelsubPBStep(ByVal mode As String, ByVal value As Integer)   the function it's calling looks like this:Private Sub pbStep(ByVal mode As String, ByVal value As Integer) Select Case mode.ToLower Case "clear" ProgressBar1.Value = 0 Case "step" ProgressBar1.PerformStep() L...

It's the fastest ''firefox'' i've ever had!!!:)
Name: Blagovest Email: blago_944atabvdotbg Product: Firefox Summary: It's the fastest ''firefox'' i've ever had!!!:) Comments: I's a great product!I'm really amazed! Browser Details: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1 From URL: http://hendrix.mozilla.org/ Note to readers: Hendrix gives no expectation of a response to this feedback but if you wish to provide one you must BCC (not CC) the sender for them to see it. ...

What's the difference between 'Build' and 'Publish'
Greetings....this subject might belong in one of the Visual Studio forums but it's so danged noob-sque.... I'm particularly confused by the 'Precompiled' term in the Publish operation. I'm interested in the path of least resistance between my VS project and my public IIS webserver. thx--steve...  Build means creating the assembly of the project ( .dll or .exe file) wich contains MSIL and a manifest file. When you publish your project u just produce the structure of your folder without producing a .dll file when you want to deploy your Web Project. ...

Parameterprefix ('@', ':', '?') with MySQL (lite) over odbc
Hi! I cant get my gridview to work with a deletecommand with a parameterprefix. I use a mysql lite installation. If a change my deletecommand to a specific id that exists in the DB everything works properly but not with @original_id (or @id). Been stuck on this for ages so I really apprechiate help. Code: asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" CellPadding="5" DataSourceID="SqlDataSource1" EmptyDataText="Det finns för närvarande inga kurser att boka." ForeColor="#333333" GridLines="None" Font-Size="Small" Width="688px" Horizon...

Web resources about - Cannot wrap 'Element''s 'addEventListener' method - mozilla.dev.tech.js-engine

Resources last updated: 12/11/2015 4:28:41 AM