ICEfaces
  1. ICEfaces
  2. ICE-9250

ace:gMap - "DOM Exception: NOT_FOUND_ERR (8)" JavaScript error when resizing the window in IE

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.3
    • Fix Version/s: EE-3.3.0.GA, 4.0.BETA, 4.0
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      Any
    • Assignee Priority:
      P2

      Description

      There is a JS error in all IE browsers when navigating the ace:gMap demos and re-sizing the browser window:

      Error in IE9:
      Message: DOM Exception: NOT_FOUND_ERR (8)
      Line: 1
      Char: 1
      Code: 0
      URI: http://10.18.39.149:8080/showcase/showcase.jsf?grp=aceMenu&exp=mapBean

      Error in IE10:
      Message: NotFoundError
      Line: 17
      Char: 473
      Code: 0
      URI: http://10.18.39.149:8080/showcase/showcase.jsf?grp=aceMenu&exp=mapBean

      It happens after navigating to a different demo and then resizing the window or maximizing/restoring it. It doesn't happen in the overview demo at first, but it does happen after navigating to another demo and then returning to the overview demo and resizing the window.

        Activity

        Hide
        Arturo Zambrano added a comment -

        When turning debugging on, the IE developer tools window shows that the error actually happens in a dynamically loaded google source file, apparently via an 'eval'.

        The error happens is not related to any ace:gMap subcomponent in particular. If the other demos are modified to just contain a simple ace:gMap instance with no other components, the error still happens.

        According to various pages, the error 'DOM Exception: NOT_FOUND_ERR (8)' is thrown because a node cannot be found. I suppose that the google gmap code registers some on-resize events on the window or document objects, which when triggered update the map instance that registered the event and the map is resized or re-centered. So, when the original node cannot be found, this error is thrown by IE.

        We've seen similar issues before, which have to do with the showcase navigation style. Perhaps, this issue could be solved by registering an onelementRemove event in our framework to remove all listeners related to a gmap instance, especially those registered on the window or document objects.

        Show
        Arturo Zambrano added a comment - When turning debugging on, the IE developer tools window shows that the error actually happens in a dynamically loaded google source file, apparently via an 'eval'. The error happens is not related to any ace:gMap subcomponent in particular. If the other demos are modified to just contain a simple ace:gMap instance with no other components, the error still happens. According to various pages, the error 'DOM Exception: NOT_FOUND_ERR (8)' is thrown because a node cannot be found. I suppose that the google gmap code registers some on-resize events on the window or document objects, which when triggered update the map instance that registered the event and the map is resized or re-centered. So, when the original node cannot be found, this error is thrown by IE. We've seen similar issues before, which have to do with the showcase navigation style. Perhaps, this issue could be solved by registering an onelementRemove event in our framework to remove all listeners related to a gmap instance, especially those registered on the window or document objects.
        Hide
        Arturo Zambrano added a comment - - edited

        Committed fix at revision 35004. Added code to trap the registration of the resize event on the window and instead use a unique listener for all the maps on the page that first checks if they still exist before updating them.

        After a lot of investigation and different attempts to fix this issue, it was found that the google code adds a great deal of listeners to various nodes related to the map and to the window object itself. One of those listeners is precisely for a resize event on the window. This was found by overriding the addDomListener function from the google code (and other listener-related functions) with a custom function that simply examines the arguments and calls the original function. There's a resize event registered on the window by the google code. It was found that this event is registered once per map on the page. Likewise, the 'NotFoundError' was being thrown once per map on the page. It was also found that most of those listeners, including the one for the resize event on the window, are not added in the constructor, but are added lazily once the map is actually loaded on the page with images and other resources taken from google's servers.

        Therefore, the fix consists in overriding the original 'google.maps.event.addDomListener' function from google with our custom function. In our custom function, we simply call the original function and pass the same arguments. After doing that we simply check if the call is for the resize event on the window, and in that case, we remove the listener by calling 'google.maps.event.removeListener' and we still return the object returned from the original 'google.maps.event.addDomListener' to identify the listener just added. This is possible because the functions in the 'google.maps.event' namespace are static and independent of any map instance (so they don't use the 'this' keyword). This is done in the 'create' method of our gmap component javascript code, since the resources that contain the 'google.maps.event' functions are lazily loaded by the google code, so we can't override the function right away. Besides doing this, we add a unique handler for the resize event on the window that checks all maps on the page and resizes them, but first checks if they still exist, in order to avoid erros being thrown.

        These changes mean that now it's not possible for users to register any custom listener for the resize event on the window via the google method (this doesn't affect at all listeners registered with jQuery or by directly using the 'resize' attribute of the window object). I tried to make the fix so that only the listener added by google gets cancelled, but it wasn't possible to identify that for two reasons: 1) if you try to use arguments.callee.caller, you get this message "Accessing the 'caller' property of a function or arguments object is not allowed in strict mode", and 2) if you try to examine the actual handler function to see if it's the one that was causing the problem, it might not be very reliable since it is minified, and the function string can change any time with changes in the minification process.

        Show
        Arturo Zambrano added a comment - - edited Committed fix at revision 35004. Added code to trap the registration of the resize event on the window and instead use a unique listener for all the maps on the page that first checks if they still exist before updating them. After a lot of investigation and different attempts to fix this issue, it was found that the google code adds a great deal of listeners to various nodes related to the map and to the window object itself. One of those listeners is precisely for a resize event on the window. This was found by overriding the addDomListener function from the google code (and other listener-related functions) with a custom function that simply examines the arguments and calls the original function. There's a resize event registered on the window by the google code. It was found that this event is registered once per map on the page. Likewise, the 'NotFoundError' was being thrown once per map on the page. It was also found that most of those listeners, including the one for the resize event on the window, are not added in the constructor, but are added lazily once the map is actually loaded on the page with images and other resources taken from google's servers. Therefore, the fix consists in overriding the original 'google.maps.event.addDomListener' function from google with our custom function. In our custom function, we simply call the original function and pass the same arguments. After doing that we simply check if the call is for the resize event on the window, and in that case, we remove the listener by calling 'google.maps.event.removeListener' and we still return the object returned from the original 'google.maps.event.addDomListener' to identify the listener just added. This is possible because the functions in the 'google.maps.event' namespace are static and independent of any map instance (so they don't use the 'this' keyword). This is done in the 'create' method of our gmap component javascript code, since the resources that contain the 'google.maps.event' functions are lazily loaded by the google code, so we can't override the function right away. Besides doing this, we add a unique handler for the resize event on the window that checks all maps on the page and resizes them, but first checks if they still exist, in order to avoid erros being thrown. These changes mean that now it's not possible for users to register any custom listener for the resize event on the window via the google method (this doesn't affect at all listeners registered with jQuery or by directly using the 'resize' attribute of the window object). I tried to make the fix so that only the listener added by google gets cancelled, but it wasn't possible to identify that for two reasons: 1) if you try to use arguments.callee.caller, you get this message "Accessing the 'caller' property of a function or arguments object is not allowed in strict mode", and 2) if you try to examine the actual handler function to see if it's the one that was causing the problem, it might not be very reliable since it is minified, and the function string can change any time with changes in the minification process.
        Hide
        Liana Munroe added a comment -

        Confirmed fixed in IE 7/9

        Show
        Liana Munroe added a comment - Confirmed fixed in IE 7/9

          People

          • Assignee:
            Arturo Zambrano
            Reporter:
            Arturo Zambrano
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: