Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Safari: new Date() prototype issue in JSNI method

    Hi,

    I am having the following issue (happens only in Safari, in other browsers: IE, Firefox, Chrome works fine):
    When new Date object is created in JSNI GWT method, it does not have extended methods in its prototype (for ex., toShortDate() method).

    Code:
    // This is just an example, not real code
    public static native Object newDate() /*-{
      return new Date();
    }-*/;
    This causes multiple issues later (ex, when this object is used in DateItem element).

    I also tried returning
    new $wnd.Date();
    new $wnd.isc.Date();
    with the same result - it always creates a Date object with base prototype methods.

    (As a workaround, I have to create Date object outside of the JSNI scope - move part of the JSNI code to a separate *.js file, but it is just ridiculous).

    the same issue happens to Array and I guess to other "system" objects as well.

    Any ideas what could be wrong? Is it a known issue? Is there a way to "fix" it?

    SmartClient: Version SC_SNAPSHOT-2010-12-15/PowerEdition Development Only (2010-12-15)
    Safari: 5.0.4
    GWT: 2.1.0

    #2
    $wnd.Date() is correct. Your team previously confirmed that this works.

    Comment


      #3
      We did not try it in Safari before.

      We indeed use this approach to create Date:

      var newDate = new $wnd.Date();

      and it works fine in IE, Firefox and Chrome. But this does not work in Safari.
      And as I wrote, it does not make a difference new Date() or new $wnd.Date() in Safari, it does not create correct object.

      NOTE: I also tried (as I wrote above)

      var newDate = new $wnd.isc.Date();
      Last edited by ESherbakova; 15 Mar 2011, 08:54.

      Comment


        #4
        Please find the screen shot from Safari debugger as a proof.
        Attached Files

        Comment


          #5
          Try

          var newDate = $wnd.Date.create();

          Comment


            #6
            Thanks, sjivan, it worked!
            I was looking for something like that.

            To Isomorphic:
            Still, I think it is worth to investigate the issue.
            It is really weird, because $wnd.Date seems to be a correct object - with correct Class, prototype and other extended properties, but creating an instance "new $wnd.Date()" returns wrong object. Why it is not working particular in JSNI?

            Exactly same issue is with new $wnd.Array().
            ($wnd.Array.create() works, because it creates the object out of JSNI scope).

            Sorry, I did not mention, I was running Safari on Windows XP (might make a difference).
            Last edited by ESherbakova; 16 Mar 2011, 05:33.

            Comment


              #7
              One problem though with using create() method:
              it accepts parameters (_1,...,_7), means create() without parameters creates an "Invalid Date" with time NaN.

              So here is an ugly workaround to create a current Date:

              var newDate = $wnd.Date.create();
              newDate.setTime(new Date().getTime());

              Comment


                #8
                ESherbakova,
                I'm not sure what you're trying to do here because all this stuff is already handled in SmartGWT. Have a look at look at the code of the various Date related API's in JSOHelper.

                For example :

                Code:
                    private static native void setDateAttribute(JavaScriptObject elem, String attr, double time) /*-{
                        var dateJS = $wnd.Date.create();
                        dateJS.setTime(time);
                        elem[attr] = dateJS;
                    }-*/;
                The issue you're seeing with Array's and Date's is not a SmartClient issue but a deep Safari / Webkit issue related to access of Array's and Date's across IFrames. I created a WebKit bug report for this a while ago and it was accepted as a P2-Major bug but has not yet been fixed.

                So if you're trying to write JSNI code related to Array's and Date's you'll need to use the create() function or simply use the JSOHelper utility methods instead.

                Sanjiv

                Comment


                  #9
                  Sanjiv, thank you for reply.

                  I am trying to fix multiple issues in our product in Safari caused by this bug.

                  1. Unfortunately, we do not use SmartGWT. It's too late to start using it at this point.
                  2. In our JSNI code we have many places when we create Array or Date objects, so now we have to replace all code to use create() method.
                  3. You could say it from the beginning - it's not fixable in Safari (it was my first question) and only one solution is to use the workaround.

                  Comment


                    #10
                    We've now added support for Date.create() being called with zero, one, or multiple arguments.
                    This will show up in the next nightly build. Here's some patch code to achieve the same thing against the build you're using in the meantime:

                    Code:
                    if (window.isc && isc.version.startsWith("SC_SNAPSHOT-2010-12-15/")) {
                        isc.addMethods(Date, {
                            create : function (arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
                                // handle being passed a subset of parameters
                                // Note that passing undefined into new Date() results in an invalid date where
                                // getTime() returns NaN
                                var undef;
                                if (arg1 === undef) return new Date();
                                if (arg2 === undef) return new Date(arg1);
                                if (arg3 === undef) arg3 = 0;
                                if (arg4 === undef) arg4 = 0;
                                if (arg5 === undef) arg5 = 0;
                                if (arg6 === undef) arg6 = 0;
                                if (arg7 === undef) arg7 = 0;
                                return new Date(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                            }
                        });
                    }

                    Comment


                      #11
                      Thank you!

                      Comment

                      Working...
                      X