This project is archived and is in readonly mode.

#801 ✓wontfix
Paolo

mootools document.id & updatePanel collision

Reported by Paolo | December 4th, 2009 @ 09:02 AM | in 1.3.0 rc2 (closed)

Hi,
I'm using mootools with asp.net.
I've already used the 1.2.2 version without any issue and in the last weeks I've started using the 1.2.4.

In this situation I've found a problem in some situation, that finally I've identified in a collision between the document.id mootools function and the microsoft code in the way they manage their UpdatePanel.

I've built a small example that can show you the error. To get the js error you need to run the web page and click in the yellow zone.
As you can see, the error disappear removing the AsyncPostBackTrigger, so we can argue that the problem is in the way asp.net manage their "async postback" when NOT using the simples <input type="button" and <input type="image",
together with the definition of document.id as a function in mootools.

this is the example that you can use to try the error (you need obviously an ASP.NET environment with the mootools library). I'm sorry, but I can't put this example in a public web server.

webform1.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3aspx.cs" Inherits="WebForm3" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



<title></title>
<script src="mootools-1.2.4-core.js" type="text/javascript"></script>
<script src="mootools-1.2.4.2-more.js" type="text/javascript"></script>



<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
    <table width="80%" border="3">
        <tr style="background-color:Yellow">
            <td>
                Label outside all the Update Panels
                <asp:Label ID="Label3" runat="Server" Font-Bold="true"></asp:Label>
                <br />
                <br />
                <asp:TextBox ID="txt" runat="server" OnTextChanged="asd_xxx" AutoPostBack="true" />
            </td>
        </tr>
        <tr>
            <td>
                <table width="65%" border="2">
                    <tr>
                        <td>
                            <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                                <ContentTemplate>
                                    Label within the Parent Update Panel
                                    <asp:Label ID="Label1" runat="server" Font-Bold="true"></asp:Label>
                                    <asp:Button ID="Button1" runat="server" Text="Refresh" />
                                </ContentTemplate>
                                <Triggers>
                                    <asp:AsyncPostBackTrigger ControlID="txt" EventName="TextChanged" />
                                </Triggers>
                            </asp:UpdatePanel>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</form>



and this is the "code behind" file webform3.aspx.cs:
using System;<br/> using System.Collections.Generic;<br/> using System.Linq;<br/> using System.Web;<br/> using System.Web.UI;<br/> using System.Web.UI.WebControls;

public partial class WebForm3 : System.Web.UI.Page {

protected void Page_Load(object sender, EventArgs e) {
    Label1.Text = System.DateTime.Now.ToString();
    Label3.Text = System.DateTime.Now.ToString();
}

protected void asd_xxx(object sender, EventArgs e) { }

}

Hope this can help. In the meantime I'll try to avoid the explicits async postbacks, renaming document.id (why not use Moo.id? it's even shorter then document.id!) or use the 1.2.2 version.

By. Paolo.

Comments and changes to this ticket

  • Scott Kyle

    Scott Kyle December 18th, 2009 @ 12:22 AM

    Hi, thanks for the detailed bug report, but we have no way of running ASP.NET code to test this out. A note for the future as well, providing server side code doesn't really help us track down the bug. Can you provide the Microsoft JavaScript code that collides with document.id?

    Thanks!

  • fakedarren

    fakedarren December 18th, 2009 @ 09:20 PM

    Hi Paolo,

    As Scott has said, it is impossible for us to give you a solution to this problem without seeing your code 'live'. If you can and want to, you can give me a shout at darren.waddell@gmail.com, and if you can give me access to your implementation, I would be more than happy to help.

    I am intrigued by this though; I would love to know about any clashes with .NET as I use it extensively at work.

    Is it just document.id? Does $ give you the same error?

    Cheers
    Darren

  • fakedarren

    fakedarren December 28th, 2009 @ 04:26 PM

    • State changed from “new” to “open”
    • Assigned user set to “fakedarren”
    • Milestone changed from 2.0 to 1.3.0 rc2

    Will try and test this over the coming weeks.

  • Paolo

    Paolo December 29th, 2009 @ 10:27 AM

    Hi Scott and Darren.

    I'm now away from work (a little holiday is needed sometimes :) )

    I'll be back on 5 january. Then I'll try to help with examples and code.

    Paolo.

  • Paolo

    Paolo January 5th, 2010 @ 01:34 PM

    Hi men,

    So I'm back. (happy new year!! ;) )

    These are the 2 main JS functions generated from Microsoft Ajax DLL that produce the error:

        function Sys$WebForms$PageRequestManager$_getPostBackSettings(element, elementUniqueID) {
            var originalElement = element;
            var proposedSettings = null;
            while (element) {
                if (element.id) {
                    if (!proposedSettings && Array.contains(this._asyncPostBackControlClientIDs, element.id)) {
                        proposedSettings = this._createPostBackSettings(true, this._scriptManagerID + '|' + elementUniqueID, originalElement);
                    }
                    else {
                        if (!proposedSettings && Array.contains(this._postBackControlClientIDs, element.id)) {
                            return this._createPostBackSettings(false, null, null);
                        }
                        else {
                            var indexOfPanel = Array.indexOf(this._updatePanelClientIDs, element.id);
                            if (indexOfPanel !== -1) {
                                if (this._updatePanelHasChildrenAsTriggers[indexOfPanel]) {
                                    return this._createPostBackSettings(true, this._updatePanelIDs[indexOfPanel] + '|' + elementUniqueID, originalElement);
                                }
                                else {
                                    return this._createPostBackSettings(true, this._scriptManagerID + '|' + elementUniqueID, originalElement);
                                }
                            }
                        }
                    }
                    if (!proposedSettings && this._matchesParentIDInList(element.id, this._asyncPostBackControlClientIDs)) {
                        proposedSettings = this._createPostBackSettings(true, this._scriptManagerID + '|' + elementUniqueID, originalElement);
                    }
                    else {
                        if (!proposedSettings && this._matchesParentIDInList(element.id, this._postBackControlClientIDs)) {
                            return this._createPostBackSettings(false, null, null);
                        }
                    }
                }
                element = element.parentNode;
            }
            if (!proposedSettings) {
                return this._createPostBackSettings(false, null, null);
            }
            else {
                return proposedSettings;
            }
        }
        
        function Sys$WebForms$PageRequestManager$_matchesParentIDInList(clientID, parentIDList) {
            for (var i = 0, l = parentIDList.length; i < l; i++) {
                if (clientID.startsWith(parentIDList[i] + "_")) {
                    return true;
                }
            }
            return false;
        }
    

    The first function is called when clicking on the page. the parameter value are:
    - element: the most inner element of the page where the user clicked, for example an HTMLTableCellElement - elementUniqueID: in my example is "undefined"

    This function cycles (while) trought the elements, and at every cycle do the last "element = element.parentNode;"
    The error happen when element is the whole document. In this case, when the second function is invocated inside the while body, the first parameter element.id is exactly the document.id function defined by Mootools.

    Thus, the clientID.startsWith is undefined and this is the error detail I can get from chrome:
    [Exception] TypeError: Object function (el, nocash, doc){

    if (el && el.$family && el.uid) return el;
    var type = $type(el);
    return (types[type]) ? types[type](el, nocash, doc || document) : null;
    

    } has no method 'startsWith'

    The expected result, without errors, would be to quit the while loop with the variable proposedSettings still null, that mean "nothing interesting in this click, no async postback required".

    I hope this can help a better understanding. I'm sorry but as I've said, I've no public space where I can put online the example page, at the moment. To do this I would have to find some free hosting site.

    Bye. Paolo.

  • Sanford Whiteman

    Sanford Whiteman January 5th, 2010 @ 08:22 PM

    • Tag changed from 1.2.4, document.id, updatepanel to 1, document.id, updatepanel

    I commented on this on the Moo mailing list.

    http://www.mail-archive.com/mootools-users@googlegroups.com/msg0878...

    I don't understand why this should be labeled a Moo defect. It's Microsoft's fault for using the existence of the id property to determine the type of the object, when there is true type checking available. Duck-typing may work if it's all their code, but they have not built for integration (surprise!) with other frameworks.

  • fakedarren

    fakedarren January 5th, 2010 @ 09:06 PM

    This is not a 'problem' with Microsoft's implementation. This is the problem we have in general, with extending prototypes. It is not a MooTools defect; it is a problem with possible conflicts with other frameworks, MS Ajax included.

    Whether we like it or not an awful lot of sites are built using .NET. From the information Pablo has provided I can see what the problem is and have no doubt we can patch it. We should look to not conflict with MS .AJAX in the same way we have provided the 'dollar safe mode' for those that wish to use MooTools with jQuery.

  • Sanford Whiteman

    Sanford Whiteman January 5th, 2010 @ 11:58 PM

    Here is your programming challenge:

    • You have an object of unknown node type.

    • You want to short-circuit processing of that object depending on its node type, specifically DOCUMENT_NODE or ELEMENT_NODE.

    • The node type can be read from the object with no possibility for error.

    • You are operating in an extensible environment using prototypal inheritance. Regardless of what properties have been added to an object or its prototype, it retains its intrinsic node type.

    • Objects of different node types can have the same named property. An object of one node type may have a fully-userland property added that has the same name as an always-on, standard property for an object of another node type.

    Do you:

    [a] set a variable named element to the object (even before you know whether it is a DOCUMENT_NODE or an ELEMENT_NODE) then check for the existence of a property that is standard on ELEMENT_NODEs and if that property exists, assume that the node type is ELEMENT_NODE, even though nothing prevents node type DOCUMENT_NODE from having a property of the same name.

    [b] read the single-valued nodeType property off the object. Using standard DOM constants, nodeType == 9 means it is a DOCUMENT_NODE, nodeType=1 means it is an ELEMENT_NODE.

    Microsoft chooses [a]. How is that choice something you should shrug off and work around as if they are not working overtime on being stupid?

  • fakedarren

    fakedarren January 6th, 2010 @ 12:58 AM

    Sandy,

    Please STFU. Yes, you are kind of right. But MS's decision to extend prototypes is no different to our own. If you want to moan keep it to the mailing list or even better come argue with me on IRC.

    This is a bug reporting forum - this 'bug' is a concern for the mootools dev team (which you are not a part of) so please keep your opinions of Microsoft to yourself and off our bug tracking list.

    Thanks
    Darren

  • Sanford Whiteman

    Sanford Whiteman January 6th, 2010 @ 01:24 AM

    Funny, my opinion of Microsoft may well be higher than yours, or at least as high... I am a proud admin of Exchange since 4.0 and run a farm of IIS 6 + 7 servers. That doesn't mean that I when I see that their code is as stupid as mine might be, it shouldn't be highlighted.

    In your zeal to attack me ("STFU"? -- okay, I hope you have a nice night), I'm not sure you're following my explanation. It's not really about competing/colliding extensions of prototypes or objects -- that is of course to be expected -- but the opposite. The Microsoft AJAX library acts as if the document object should not be treated as extensible: if varname.id exists, that means to them that varname must be an element, since only elements have ids. I don't know how you can work around that kind of assumption on the Mootools side unless you go fully namespaced, never touching natives. I hope you can figure something out, but it's trivial to come up with more code like theirs that doesn't sufficiently introspect (or whatever you call it) natives and seems to "collide" with Moo. Best of luck though, didn't mean to pollute the bug tracker,

  • Paolo

    Paolo January 7th, 2010 @ 10:02 AM

    hi swhiteman,

    I want to say only that I've never spoken about a mootools defect, as you should understand reading my messages.

    I've only reported what can happen under some circumstances. This can be of some interest for the mootools team, or not and this is not a problem for me. Anyway, if the team is interested I can give some support, gathering information.

    So, before speaking about defects, let me say that you should read carefully what other person wrote.

    Bye. Paolo.

  • Sanford Whiteman

    Sanford Whiteman January 7th, 2010 @ 10:23 PM

    Yes, a "collision" may be taken as single or dual defects, or none at all; it's not really an evolved term. Could just be an situation worth remarking on, say on your personal blog. But you submitted this to an issue tracker for product X and suggested a dramatic change to X's most current code ("why not use Moo.id? it's even shorter then [sic] document.id!") -- implying, perhaps accurately from the integration standpoint, a regression in X 1.2.4.2. You remarked that you would have to stay with an earlier version of X or hack your own X in order to use X and Y together. And a dev for X thanked you for the "bug report". You didn't even open a ticket with product Y's developers (I checked before doing this myself). Whether you meant to or not, you were treating this as a defect in X and a non-issue for Y, and your ticket was so interpreted.

    (Really, it just felt right to come back and attack someone who is exploring and defending the choices of the X team -- not just being knee-jerk anti-Y -- on the X issue tracker? Someone who even contributed an external workaround for the issue?)

  • fakedarren

    fakedarren January 7th, 2010 @ 10:33 PM

    Please move future discussion to the MooTools Users Google group. We already have a patch and just need to test.

  • Che Goluska

    Che Goluska April 22nd, 2010 @ 10:08 PM

    Any more on fixing this like when it might happen? I worked around it by fixing the ASP.Net script to use node type "(f.nodeType === 1)" instead of seeing if id is defined and overriding the script src it with

    <asp:ScriptReference name="MicrosoftAjaxWebForms.js" Path="~/ui/formats/general/jscripts/MicrosoftAjaxWebForms.js"/>
    

    I'd rather not have to override base M$ scripts though, or maintain them.

  • Christoph Pojer

    Christoph Pojer September 4th, 2010 @ 11:20 AM

    • State changed from “open” to “wontfix”
    • Milestone order changed from “0” to “0”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins

Attachments

Pages