preventing Prototype from extending HTMLElement.prototype

4 views
Skip to first unread message

RighteousRaven

unread,
Jun 13, 2007, 3:25:11 PM6/13/07
to Ruby on Rails: Spinoffs
Debugging IE is a serious pain in the neck, and I am running into bugs
because IE doesnt allow extension of HTMLElement.prototype. I want to
temporarily prevent Prototype from extending HTMLElement.prototype in
Firefox so I can use firebug to burn all those nasty little buggers.
Does anyone have any ideas on how to do this?

Thanks
RR

Ken Snyder

unread,
Jun 13, 2007, 4:38:59 PM6/13/07
to rubyonrail...@googlegroups.com
Never tried, but you could try messing with Prototype.BrowserFeatures.
Let us know what you find; sounds interesting.

--Ken


In prototype.js 1.5.1 line 21
-- ElementExtensions: !!window.HTMLElement,
++ ElementExtensions: false,

and comment out lines 1819-1824
/*if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement('div').__proto__) {
window.HTMLElement = {};
window.HTMLElement.prototype = document.createElement('div').__proto__;
Prototype.BrowserFeatures.ElementExtensions = true;
}*/

RighteousRaven

unread,
Jun 13, 2007, 5:27:28 PM6/13/07
to Ruby on Rails: Spinoffs
I got it working. The only change from Ken's suggestion is to also
set SpecificElementExtensions to false. I had to upgrade to 1.5.1
cause I couldn't figure it out on 1.5.0.

Thanks for your help Ken,

RR

Andrew Red

unread,
Jul 18, 2007, 9:22:49 AM7/18/07
to Ruby on Rails: Spinoffs
You know, Gentlemen,
I became aware of SpecificElementExtensions only because my FF 2.0.xxx
started blurting out errors with Prototype v 1.5.1.1 that certain
functions on extended DOM elements ( $(..) ) don't actually exist.
Then I found SpecificElementExtensions, and then - this pretty
discussion.

Hasn't it been tested, that apparently Prototype v1.5.1.1 doesn't work
well with FF 2.0? How come no one gets warned from http://prototypejs.org's
blog? Aah.

Anyhow, thanks for the suggestions on this point. It worked with me.

BrowserFeatures: {
XPath: !!document.evaluate,
ElementExtensions: false, //!!window.HTMLElement,
http://groups.google.com/group/rubyonrails-spinoffs/browse_thread/thread/b2c29ae55f5e9739/76664ecad4546be4?lnk=gst&q=SpecificElementExtensions&rnum=1#76664ecad4546be4
SpecificElementExtensions: false
/*
(document.createElement('div').__proto__ !==
document.createElement('form').__proto__)
*/
}

and..

#1828, after "Object.extend(Element, Element.Methods);":

/*
http://groups.google.com/group/rubyonrails-spinoffs/browse_thread/thread/b2c29ae55f5e9739/76664ecad4546be4?lnk=gst&q=SpecificElementExtensions&rnum=1#76664ecad4546be4


if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement('div').__proto__) {
window.HTMLElement = {};
window.HTMLElement.prototype =
document.createElement('div').__proto__;
Prototype.BrowserFeatures.ElementExtensions = true;
}*/

Works well. Thanks once again. Waiting for the working update.


Best regards,

Andrew Revinsky


On Jun 14, 1:27 am, RighteousRaven <righteousra...@gmail.com> wrote:
> I got it working. The only change from Ken's suggestion is to also

> setSpecificElementExtensionsto false. I had to upgrade to 1.5.1

> > }*/- Hide quoted text -
>
> - Show quoted text -

Tobie Langel

unread,
Jul 18, 2007, 11:17:48 AM7/18/07
to Ruby on Rails: Spinoffs
Hi Andrew,

Could you be a it more specific and / or open a ticket for the missing
methods, as this issue is unheard of as far as I know.

If this is true it is definitely a bug and needs to be dealt with.

Thanks and best regards,

Tobie

Andrew Red

unread,
Jul 24, 2007, 8:39:57 AM7/24/07
to Ruby on Rails: Spinoffs
Tobie, hello!

I use FF 2.0.x.x with Firebug on Win XP RU. I'm not sure if the latter
part matters, anyhow.

Just after I've upgraded to 1.5.1.1, all calls to $() function were as
if I just did document.getEl..tById(), not extended. And it was so
only in FireFox. However, in IE elements were extended fully.

So I noticed FireBug was giving me errors like ".up() method is null
or undefined" and ".addClassName method is null or undefined" (and
such).

Tracing back the callstack I figured, the Element.extend method was to
blame. There's an "if" statement (the second line):

if (!element || !element.tagName || element.nodeType == 3 ||
element._extended || F.SpecificElementExtensions || element ==
window) ...

And in my FF, F.SpecificElementExtensions always resolved to true,
while in IE - false. So, in FF, the element was returned back, having
no extended methods whatsoever. Really upset me.

I first checked your blog, then went here. Just to find that mild
solution to my problem by eliminating those niceties. I believe, this
describes my problems.


Oh, by the way, is the $$() function supposed to return unextended
elements?

Like, I happen to use $() so that this snippet would work (3rd line):

$$('.menuBar a').each(function(el) {
if (!window.location.href.endsWith(el.href)) return;
$(el).addClassName('selected').up(0).addClassName('selected');
throw $break;
});

Thanks!


Best regards,

Andrew Revinsky

> > functions on extended DOM elements ( $(..) ) don't actually exist.- Hide quoted text -

Tobie Langel

unread,
Jul 24, 2007, 1:22:33 PM7/24/07
to Ruby on Rails: Spinoffs
Hi Andrew,

You're misunderstanding a lot of different things here.

I suggest you read the article "How Prototype Extends the DOM":
http://prototypejs.org/learn/extensions

Hope that helps.

Regards,

Tobie

pointym5

unread,
Jul 30, 2007, 1:46:17 PM7/30/07
to Ruby on Rails: Spinoffs
On Jul 24, 12:22 pm, Tobie Langel <tobie.lan...@gmail.com> wrote:
> Hi Andrew,
>
> You're misunderstanding a lot of different things here.
>
> I suggest you read the article "How Prototype Extends the DOM":http://prototypejs.org/learn/extensions

The problem appears to be that the test in BrowserFeatures to know
whether to set SpecificElementExtensions to true or false is returning
"true" in Firefox 2.0.x.x. Therefore, in Element.extend, all of the
code to actually perform the extensions are not called.

"So?" you may ask. "Surely the point of the test is that the
extensions don't need to be done; that's the whole point of that
flag." Generally that's true - but what about when code in one
document is called from code in another document, one which doesn't
even include prototype.js?

It is in exactly this case that I'm being affected by the behavior. My
application involves a lot of iframes, and a *lot* of pages. We've
only begun using prototype lately, so many legacy pages do not yet
include prototype.js. When a call is made via a reference to "top" or
"parent", things can go wrong.

Andrew Red

unread,
Aug 2, 2007, 7:56:31 AM8/2/07
to Ruby on Rails: Spinoffs
That is a very strong statement, Tobie. Overly. Thank you very much. )

I'd rather you break it down to parts. Like, "that particular snippet
of yours.." or somethin'. 'Cos "I've eaten a god on Prototype" (how
they say it in our lands) by now. I understand you're in the Prototype
team and all. And the rest of the world knows much less about this
child than you do.. ) But.. I, too, regularly study all changes even
to minor versions and have created a Prototype reference cheatsheet
for colleagues way before it was available on the web.

Now, what I understand about "F.SpecificElementExtensions", it doesn't
necessarily return the right value when it should. That's the fact.
I've given you an example. Perhaps, some FF plugins were preventing it
from working the right way.

Then, second question, what I understand about $$(), it returns a
plain array with unextended elements (if IE is used, for instance). Is
it by design?

Thanks.

Best regards,
Andrew Revinsky

> > > - Show quoted text -- Hide quoted text -

Christophe Porteneuve

unread,
Aug 2, 2007, 9:07:21 AM8/2/07
to rubyonrail...@googlegroups.com
Hey,

I can't believe this thread is so long... There's just no way we won't
extend prototypes on elements, I think. It's at the core of what we do.

Andrew Red a écrit :


> Now, what I understand about "F.SpecificElementExtensions", it doesn't
> necessarily return the right value when it should. That's the fact.

Sounds weird, and you're welcome to submit a reproduceable case and the
matching tested patch to the Trac.

> Then, second question, what I understand about $$(), it returns a
> plain array with unextended elements (if IE is used, for instance). Is

Actually this is incorrect. $$ branches out to either the browser's
native DOM Level 3 XPath support or its internal matcher. Both do
return actual JS arrays.

If in the former case, it doesn't bother extending the results, because
it doesn't need to: DOM 3 XPath is supported only on browsers (Opera,
FF, WebKit) that happen to feature HTMLElement.prototype, so we're
pretty much in the clear: the only sore point you might hit is
tag-specific extensions on Opera, which would require an extra $ call.

In the latter case (custom JS matcher), elements are extended as their
internal duplicates are filtered out, in Selector.handlers.unique. So
all extensions, be they generic or tag-specific, are guaranteed. This
applies in MSIE and Safari, and only causes delay in MSIE (if your $$
resultset is very large).

'HTH

--
Christophe Porteneuve aka TDD
t...@tddsworld.com

Andrew Red

unread,
Aug 2, 2007, 9:46:17 AM8/2/07
to Ruby on Rails: Spinoffs
Hmm, thanks.

pointym5

unread,
Aug 5, 2007, 2:03:10 PM8/5/07
to Ruby on Rails: Spinoffs

On Aug 2, 8:07 am, Christophe Porteneuve <t...@tddsworld.com> wrote:
> Hey,
>
> I can't believe this thread is so long... There's just no way we won't
> extend prototypes on elements, I think. It's at the core of what we do.

Yes, there definitely is a way, in Firefox:

1) Create a page with an iframe. The page should import prototype.js.
2) Create a page to be loaded in the iframe. That page should *not*
import prototype.js.
3) Have the iframe page call
"parent.something(document.getElementById('x'))", such that the parent
"something" function calls $(arg) on its argument and then expects the
object to have all the Prototype element extensions.
4) Boom.

"That's silly", you may say, "just import prototype in your iframe
page." That is indeed the best approach to take, but it's a non-
trivial issue in an extensive application with hundreds of pages that
all use services on the "top" page. The "top" code cannot expect
using $() to extend correctly incoming (as parameters) elements until
all pages have been changed to import Prototype.


Andrew Red

unread,
Aug 16, 2007, 3:58:24 AM8/16/07
to Ruby on Rails: Spinoffs
Pointy5,

I've run across the issue similar to it. I ruled it out with the
notion of the following:
When you call functions accross windows, the call chain tracks you
back to the original window (windows have separate JS engines). So
even if you're searching for element in window "A" having started from
window "B", the code of $() function will do the seeking in the "B"
window. In order to break the call chain, you (I did it) have to set a
timeout on window "A" (having started from "B" window) with minimal
time (0 or 1) to call a function local to "A" to do the rest. This
breaks the chain, 'window' object hereafter will refer to window "A",
not "B". To make the call safe.

With best regards,

Andrew

Reply all
Reply to author
Forward
0 new messages