sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    JSON in Ruby

    Scheduled Pinned Locked Moved Developers' Forum
    48 Posts 7 Posters 7.0k Views 7 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M Offline
      Myhand
      last edited by

      OK, with the single quote now working, I have run into the next (and hopefully the last) problem. It appears as if the

      WebDialog.execute_script

      method strips all \ characters from its arguments as it passes it into JavaScript. I think it is because it does a eval() call on the JS.

      e.g.

      js_command = "material_maintenance.Sketchup.callUI(\"a string >\\< with a \\\" in the middle\")"; puts "js_command = #{js_command}";

      produces this in the Ruby console:

      
      js_command = material_maintenance.Sketchup.callUI("a string >\< with a \" in the middle")
      
      

      and this when you print the parameter to the callUI function as it hits JS.

      
      a string >< with a " in the middle 
      
      

      replacing js_command with

      js_command = "material_maintenance.Sketchup.callUI(\"a string >\\u005c\\u0022< with a \\u005c\\u0022 in the middle\")"

      works and produces the desired output in JS

      
      a string >\"< with a \" in the middle
      
      

      but this feels a bit clunky. Any other ideas?

      http://www.keepingmyhandin.com/

      1 Reply Last reply Reply Quote 0
      • A Offline
        Aerilius
        last edited by

        1. You need to escape \ characters in the double-quoted javascript code that you want to bring into the webdialog (this first escaping is what makes a valid Ruby string).
          %(#000000)["alert('C:\users')"] # bad Ruby string
          %(#000000)["alert('C:\\users')"] # good Ruby string
        2. In the webdialog, the string arrives written in a script element. As always, the same escaping rules apply again:
          %(#000000)[alert('C:\users')] // bad JavaScript code
          %(#000000)[alert('C:\\users')] // good JavaScript code

        => So finally this means we need double escaping on the Ruby side!
        %(#000000)["alert('C:\\\\users')"] # Ruby string

        P.S: SketchUp does not offer error handling for syntax errors in the Ruby-to-JavaScript string. Assuming my js contains user generated data with unknown characters, or is broken (truncated), we will definitely get a popup about "Syntax Error" that we cannot suppress and handle in other ways. In order to get control of such errors, we could send the code as a JavaScript string and eval() it:
        %(#000000)[webdialog.execute_script("try{eval(\"}bad_$yn7aX{\")}catch(e){}")]

        All of this is an old story and to many people have suffered, discovered, solved this and re-invented the wheel. For an all-in-one solution that covers this and many other WebDialog issues (for example you will discovered that when sending \\\ from JS to Ruby, it randomly drops some ), please take a look and make use of the WebDialogX project.

        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by

          @myhand said:

          method strips all \ characters from its arguments as it passes it into JavaScript. I think it is because it does a eval() call on the JS.

          Almost - it injects a SCRIPT element in the webdialog - does pretty much the same thing.
          So when you pass data to the WebDialog and something is amiss - check the string you're sending to the WebDialog - is it valid? What throws people off is that you have the quoting needed to create the Ruby string with the JS - and within the JS string you need to follow JS's own quoting and escaping rules.

          (Because execute_script adds a SCRIPT element for every call I prefer to remove the SCRIPT element on the JS side afterwards - as I don't like the idea of the DOM tree flooded with SCRIPT elements. I've yet to experience problems with it - but there's something about it that makes my OCD-nerve tingle.)

          Thomas Thomassen β€” SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • M Offline
            Myhand
            last edited by

            @aerilius said:

            => So finally this means we need double escaping on the Ruby side!
            %(#000000)["alert('C:\\\\users')"] # Ruby string

            I am sure I tried this last night, but will do some further tests again tonight.

            @aerilius said:

            In order to get control of such errors, we could send the code as a JavaScript string and eval() it:
            %(#000000)[webdialog.execute_script("try{eval(\"}bad_$yn7aX{\")}catch(e){}")]
            [/size]

            Nice idea, I might use this going forward.

            @aerilius said:

            please take a look and make use of the WebDialogX project.

            I cannot access the content. I get "You do not have access to the wiki." message, even after I have registered.

            http://www.keepingmyhandin.com/

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              @myhand said:

              @aerilius said:

              please take a look and make use of the WebDialogX project.

              I cannot access the content. I get "You do not have access to the wiki." message, even after I have registered.

              Sorry, it is a 5-slot private repository at this time, and we really need very experienced Rubyists for the slots.

              And you are kinda re-inventing the wheel. Js has %(#8000BF)[escape()] and %(#8000BF)[unescape()], and Ruby has them in the URI library.

              See topic: http://sketchucation.com/forums/viewtopic.php?f=180&t=49183#p442102

              In fact I would vote for Ruby's URI::Escape module to be mixed into the SketchUp API UI::WebDialog class.

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • M Offline
                Myhand
                last edited by

                @dan rathbun said:

                Sorry, it is a 5-slot private repository at this time, and we really need very experienced Rubyists for the slots.

                No problem Dan, I only looked there as Aerilius recommended I do so.

                @dan rathbun said:

                And you are kinda re-inventing the wheel. Js has %(#8000BF)[escape()] and %(#8000BF)[unescape()], and Ruby has them in the URI library.

                See topic: http://sketchucation.com/forums/viewtopic.php?f=180&t=49183#p442102

                In fact I would vote for Ruby's URI::Escape module to be mixed into the SketchUp API UI::WebDialog class.

                Thank you, I will try the URI library (I already use escape() in my latest JS code). I do not really want to reinvent the wheel, hence me asking the question here.

                http://www.keepingmyhandin.com/

                1 Reply Last reply Reply Quote 0
                • M Offline
                  Myhand
                  last edited by

                  @aerilius said:

                  1. You need to escape \ characters in the double-quoted javascript code that you want to bring into the webdialog (this first escaping is what makes a valid Ruby string).
                    %(#000000)["alert('C:\users')"] # bad Ruby string
                    %(#000000)["alert('C:\\users')"] # good Ruby string
                  2. In the webdialog, the string arrives written in a script element. As always, the same escaping rules apply again:
                    %(#000000)[alert('C:\users')] // bad JavaScript code
                    %(#000000)[alert('C:\\users')] // good JavaScript code

                  => So finally this means we need double escaping on the Ruby side!
                  %(#000000)["alert('C:\\\\users')"] # Ruby string

                  Thanks for a very clear explanation. πŸ‘ I tried this last night and it worked. Need 7 '''s for a "!

                  http://www.keepingmyhandin.com/

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by

                    @myhand said:

                    Need 7 '''s for a "!

                    ❓ ❓

                    What?

                    Thomas Thomassen β€” SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • M Offline
                      Myhand
                      last edited by

                      @dan rathbun said:

                      And you are kinda re-inventing the wheel. Js has %(#8000BF)[escape()] and %(#8000BF)[unescape()], and Ruby has them in the URI library.

                      See topic: http://sketchucation.com/forums/viewtopic.php?f=180&t=49183#p442102

                      Thanks for this Dan! It works well, and I do not need to remember the number of slashes. πŸ˜„

                      I see that escape() and unescape() are deprecated though and that you are recommended to use

                      decodeURI()
                      
                      decodeURIComponent()
                      

                      Which do you recommend or should I continue with unescape()?

                      http://www.keepingmyhandin.com/

                      1 Reply Last reply Reply Quote 0
                      • M Offline
                        Myhand
                        last edited by

                        @thomthom said:

                        @myhand said:

                        Need 7 '''s for a "!

                        ❓ ❓

                        What?

                        Sorry, meant you need

                        "a JSON escaped double quote need to be specified like this \\\\\\\" in Ruby for a WebDialog call"

                        to produce

                        "a JSON escaped double quote need to be specified like this \" in Ruby for a WebDialog call"
                        

                        as the parameter of the JS function called.

                        http://www.keepingmyhandin.com/

                        1 Reply Last reply Reply Quote 0
                        • Dan RathbunD Offline
                          Dan Rathbun
                          last edited by

                          Hmmm..

                          given a Js function named say()

                          .. and a Ruby string:
                          jarg = %q('a JSON escaped double quote need to be specified like this %q(\") in Ruby for a WebDialog call')

                          I usually do something like this:

                          dlg.execute_script("say(#{jarg});")

                          or I will leave the single quotes out of the jarg string, and put them in at the call ...

                          jarg = %q(a JSON escaped double quote need to be specified like this %q(\") in Ruby for a WebDialog call.)
                          dlg.execute_script( "say('" << jarg << "');" )

                          πŸ’­

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • Dan RathbunD Offline
                            Dan Rathbun
                            last edited by

                            [quote="Myhand":31wco2xd]I see that %(#8000BF)[escape()] and %(#8000BF)[unescape()] are deprecated (in Javascript,) though, and that you are recommending to use [them]
                            ***%(#BF4000)[
                            @unknownuser said:

                            ]***

                            @unknownuser said:

                            ](http://msdn.microsoft.com/en-us/library/dz4x90hk(v)":31wco2xd]The unescape function should not be used to decode Uniform Resource Identifiers (URI). Use decodeURI and decodeURIComponent functions instead.
                            %(#8000BF)[decodeURI()]
                            %(#8000BF)[decodeURIComponent()]

                            Which do you recommend or should I continue with %(#8000BF)[unescape()]?

                            The old functions are ASCII, the new ones are Unicode.

                            Taking a look at the most recent released ECMA-262 (but not the latest proposed revision,) the old functions are no longer listed.

                            see: ECMA-262, 5.1, Global Object: 15.1.3 URI Handling Function Properties
                            ECMAScript Language Specification
                            Standard ECMA-262
                            5.1 Edition / June 2011

                            Link to the downloadable PDF of the specification.


                            But you need to handle the situation where an older browser does not have these functions so, write a wrapper in JS:

                            var unesc = function(uri) {
                                var test = false;
                                if (typeof(decodeURI) == "function") test = true;
                                return test ? decodeURI(uri) ; unescape(uri);
                            }
                            

                            πŸ’­

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • 1
                            • 2
                            • 3
                            • 3 / 3
                            • First post
                              Last post
                            Buy SketchPlus
                            Buy SUbD
                            Buy WrapR
                            Buy eBook
                            Buy Modelur
                            Buy Vertex Tools
                            Buy SketchCuisine
                            Buy FormFonts

                            Advertisement