Are the calls to the 2024 and 2023 html windows significantly different from 2022 and lower?

Hi Seniors, are the 2024 and 2023 html window calls significantly different from 2022 and lower versions? Because when I use the same code and test it on 2022 and below, the frontend can call the local callbacks normally, but 23 and 24 show the error message in the picture, I’m not quite sure what happened, is it due to the change to the QT framework? I am not sure what is going on here, is it due to the change to the QT framework and how can I fix it? I’m not sure what’s happening here!

Firstly, I never have had a need to prefix the sketchup JS object with window.

Secondly, SU 2023 and 2022 both used the same Chromium framework v 88.
It is SU 2024 that jumped way up to version 112.


It just looks like a picky VueJS error to me. You might check and see if there is a newer version of VueJS available.

Maybe try the following in the js console and see what it lists:

Object.getOwnPropertyNames(sketchup).sort()

In 2024 in certain situations the javascript sketchup object fails to completely initialize - all the action_callbacks are missing, but there is no error or explanation why.

        success = @dialog.add_action_callback("close") do |ctx, args|
          self.clear_observers()
        end
        puts "bind_actions close success: #{success}" if PFPSketch.debug?
        # This logs success: true

In javascript, it is as if the dialog was not initialized.

Object.getOwnPropertyNames(sketchup).sort()
(5) ['LoginSuccess', 'LogoutSuccess', 'installRBZ', 'launchEW', 'openExternalUrl']

This is deterministic - if I run my extension and try to model a new building it happens every time, but other workflows the dialog callbacks work as normal. The bug only exists in 2024 and in 2023/2022 callbacks do not disappear after being added.

Attach callbacks to the dialog object (inside a method that can be recalled as needed.)
If the user closes the dialog window the callbacks are detached. If the dialog is reopened (via your extension command) the callbacks must be reattached (using the method as described.)

def my_command
  if @dialog
    if @dialog.visible?
      @dialog.bring_to_front
    else
      attach_callbacks()
      @dialog.show
    end
  else
    create_dialog()
    attach_callbacks()
    @dialog.show
  end
end

Try to determine the exact “certain situations” that this happens if not as I describe. Knowing when it fails will be the biggest step toward getting it fixed. (A reproducible minimum code snippet is even better.)


P.S. - @Rubert There is no Make 2018 edition (ie, your forum profile.)

Attach callbacks to the dialog object (inside a method that can be recalled as needed.)
If the user closes the dialog window the callbacks are detached . If the dialog is reopened (via your extension command) the callbacks must be reattached (using the method as described.)

Thanks Dan.

Yes, it’s done inside a method. The bug happens immediately when the HtmlDialog window opens - before any user interaction is possible. add_action_callback returns true, but when the DOM loads none of the callbacks are available from javascript.

I tried to make a simpler example but the callbacks do work correctly there. This is a fairly complex scenario to try to isolate. I will try to get the 2024 debugger working and see if I can get any more information from that.

Not sure where you are seeing Make 2018 - I am using Pro 2022/2023/2024 now on Windows 11 64 bit.

Then, your forum profile is way out of date.

Try using the window "load" event.
It is supposed to fire after document.readystate === "complete".

I’ve also found in some cases that I needed to introduce a short delay in doing stuff after the dialog webpage loads.

Here is a JavaScript snippet from my last example:

    // Ready state function to notify the Ruby-side dialog object.
    //
    // This event handler will fire a Ruby callback that notifys the
    // Ruby-side that the webpage has fully loaded.
    function dialog_ready() {
        //console.log('In "dialog_ready" event handler.');
        sketchup.dialog_ready("",
          {
            onCompleted: function() {
              console.log('Ruby callback "dialog_ready" has returned.');
            }
          }
        );
    }

    // Sometimes the dialog_ready function is firing the Ruby callback before
    // the page is rendered so we will try a delay here.
    function document_ready() {
        //console.log('In "document_ready" event handler.');
        var id = setTimeout(dialog_ready, 300); // milliseconds
    }

    // Attach a listener to the window to fire the ready state function:
    //
    // After document.readyState === "complete" the page supposedly has been
    // completely loaded including all resources. The load event then fires.
    window.addEventListener("load", document_ready);

First of all, I haven’t seen the issue you’re seeing (failed callbacks). But there may be some things I haven’t checked.

I’ve got code for a plugin that was originally written for SU 8. At some point, I updated it for UI::HtmlDialogs, maybe in 2017. I happen to be updating it now, so I’ve been checking the dialogs, as I never wrote any tests for it.

It does some modification of the html, but dialogs are modified with a set of DOM js methods that are called via execute_script. It also wrapped a lot of things to make debugging easier. So, I had one js function named talk that wrapped calls to the sketchup object, something like:

const talk = (cb, data) => {
  if (typeof(window.sketchup[cb]) === 'function') {
    sketchup[cb](data);
  } else {
    alert(`${cb} is not registered as a callback`);
  };
};

I changed the code in one dialog so it called an undefined callback which was used for DOMContentLoaded.

On SU 2023, the alert is triggered. On SU 2024, the alert is not triggered.

But, if I open ‘DevTools’, it shows the correct array for Object.getOwnPropertyNames(sketchup).sort().

So, your statement below is correct. Or, this is a bug in SU 2024.

In 2024 in certain situations the javascript sketchup object fails to completely initialize

1 Like

Struggling with this too!

Ok, more investigation.

In 2024, it looks like I can get a consistent experience, if call dialog.add_action_callback every time immediately before the dialog is made visible.

these calls must be made while the dialog is invisible.

So, this works:

  1. create the dialog
  2. (it’s not yet visible, so) dialog.add_action_callback
  3. show dialog
  4. Object.getOwnPropertyNames(sketchup).sort() includes “say”
  5. hide dialog
  6. call dialog.add_action_callback
  7. show dialog
  8. Object.getOwnPropertyNames(sketchup).sort() includes “say”

if you skip step 6, step 8 does not include “say”

Did you try with SU2024 Build 553?

It seems that something has fixed (or changed) in the Load sequence of HtmlDialogs.

See this post, at least for one issue which seems to be fixed with the update to SU2024.

Running 24.0.554 on mac.

Subscribed to the GH issue

It has always been thus.

The documentation for the UI::HtmlDialog#add_action_callback method clearly states …

Note: When an HtmlDialog is closed, all callbacks to that instance are cleared. Re-attach them if you need to open the dialog again.

This is why I always put the calls to #add_action_callback within a method by themselves that can be recalled when the dialog is reshown.

1 Like

Ok, I think I narrowed down the difference. I was calling dialog.show and then add_action_callback - which did work in 2017-2023, but does not consistently work in 2024. I reversed the order of calls as suggested and that appears to have solved my issue.

This example is the method we are now using - very similar to Dan’s example above. htmldialog-examples/src/step05.rb at main · SketchUp/htmldialog-examples · GitHub

@DanRathbun - would it be possible to get a more fleshed out example added or linked from the add_action_callback docs please? Your example or the htmldialog-examples link had the missing piece of info about the order of calls needed.

P.S. - @Rubert There is no Make 2018 edition (ie, your forum profile.)

Fixed

Try using the window "load" event.
It is supposed to fire after document.readystate === "complete" .

It appears like the sketchup javascript object is being initialized earlier in the process - before the DOM fully loads. There is no external script resource being loaded for it, so I guess it is being bundled at the Chromium level? I guess this explains why you need to bind events before showing the dialog.

1 Like

Yea, makes sense to me.

I don’t control the official public API documentation (which is full of errors, BTW.)

You can open a documentation issue in the official API Issue tracker.

You could start some kind of tips & tricks database organized by class and method of your own.

Or download the Ruby API stubs, standalone Ruby and YARD and do your own edits and generate your own local documentation. (The learning curve is steep for this option though.)