WebDialogs - The Lost Manual — R1 09 November 2009
-
Revision: R1 - 09 November 2009
This topic is outdated!
[highlight=#ffffbf:1chqwlqg]In order to better maintain The Lost Manual I am moving it from a long single page PDF/forum post/blog article to a better structured GitHub repository with Wiki articles detailing issues, how-to and best practices as well as sample files and Issue tracker.
It's still rough around the edges as information is ported from the old manual and lingering notes, but please join in on the contribution and share your insight! Get your fork out![/highlight:1chqwlqg]
https://github.com/thomthom/sketchup-webdialogs-the-lost-manual
I've recently been working more with WebDialogs and I have noticed there's a great deal of got-cha's which is not mentioned in the documentation, which you can find buried in this forum. Therefore I want to collect all this info into one single post where all the important stuff is in the top - not scattered in various threads or buried deep in a topic. Please drop me a message or add a comment to this thread for more information to add.
Overview
-
Cross Platform
-
Async vs sync Communication
-
window.onload
-
WebDialog.show
/WebDialog.show_modal
-
Quirks vs Standard vs Superstandard
-
HTML, CSS and Javascript
-
WebDialog.new
-
Comma Separated Arguments
-
Hash argument
-
Fixed window size
-
Scrollbars
-
Paths -
WebDialog.set_file
vsWebDialog.set_html
-
Bugs and Issues
-
OSX
.execute_script
and quotes -
WebDialog Javascript callback Maximum message size
-
#<Exception: Invalid Dialog>
-
<LocalJumpError: return from proc-closure>
in WebDialog -
Debugging
-
Thanks
Cross Platform
Async vs sync Communication
On PC the communication between javascript and ruby is synchronous. That means when you call a ruby method usingwindow.location = 'skp:rubyMethod'
, the javascript will wait for the ruby method to complete before proceeding with the next javascript statement.On OSX it just sends the command and continues with the javascript without waiting - making it impossible call sequential callbacks to ruby too quickly as they will override each other.
Calling from ruby to javascript using
.execute_script
is synchronous on both platforms. The method will wait for the javascript to finish before processing next line of ruby.So you can do stuff like this:
dialog.execute_script('add(2,3);') value = dialog.get_element_value('sketchupPump')
The add javascript function will here take both arguments and add them together and put the value into a hidden input field with the id 'hidden_input'.
function add(n1, n2) { document.getElementById('sketchupPump').value = n1 + n2; }
The input field in the HTML is something like this:
<input id="sketchupPump" type="hidden">
Further reading:
- http://forums.sketchucation.com/viewtopic.php?f=180&t=13394
- http://forums.sketchucation.com/viewtopic.php?f=180&t=22698
- There's more threads on this topic - but I've not been able to collect them all.
window.onload
On Windows, the HTML document appear to be created when you calldialog.show
. If you attach an event towindow.onload
which send a command back to ruby to print"Hello World"
in the console you'll see"Hello World"
printed as you call.show
. But on OSX it seems that the HTML document is created as you use.set_file
or.set_html
- before calling.show
.
Example script:module TT_Test @d = nil @d = UI;;WebDialog.new('On Load Test') @d.add_action_callback('onload') { |dialog, params| puts '>> window.onload' } @d.set_html('<html><body onload="window.location=\'skp;onload\';">Onload Test</body><html>') def self.onload @d.show { puts '>> ruby block' } end end
On Windows, when you run the script:
[ruby:1chqwlqg]load 'test/webdialog.rb'
true
TT_Test.onload
trueruby block
window.onload[/ruby:1chqwlqg]Notice that the ruby block executes before the WebDialog [ruby:1chqwlqg]onload[/ruby:1chqwlqg] event, which might indicatethe block is run before the HTML document is ready.
On OSX:
[ruby:1chqwlqg]> load 'test/webdialog.rb'
truewindow.onload
TT_Test.onload
true[/ruby:1chqwlqg]Notice that window.onload triggers immediately as we've added the HTML to the WebDialog object. And that the
.show
block never executes.So if you create a WebDialog object when you load your plugin, beware that it will consume resources from the moment you add the HTML and not wait for the dialog to actually show.
WebDialog.show / WebDialog.show_modal
On OSX, [ruby:1chqwlqg].show_modal[/ruby:1chqwlqg] only makes the window stay on top of the Sketchup window, but the window is not really modal.On PC the window always stays on top of Sketchup, but [ruby:1chqwlqg].show_modal[/ruby:1chqwlqg] is truly modal.
It also seems that when you pass a block along with.show
or [ruby:1chqwlqg].show_modal[/ruby:1chqwlqg], the block will never execute on OSX.Quirks vs Standard vs Superstandard
When you create a HTML document, it behaves differently depending on the DOCTYPE you choose. You must choose the DOCTYPE you want to work with. For further reading: http://www.quirksmode.org/css/quirksmode.htmlNote! Because WebDialogs are embedded browser controls they behave differently than a normal website on Windows. Internet Explorer 8, as a browser, will default to Super Standard mode when you use Strict DOCTYPE. But when embedded as a WebBrowser object it will default to IE7 compatibility mode. Microsoft says that you have to set a registry key for the application that embeds the WebBrowser to make it use IE8 rendering mode. But of course we can't do that for Sketchup since some plugins might rely on the IE7 mode.
But what you can do is include the meta tag [ruby:1chqwlqg]<meta http-equiv="X-UA-Compatible" content="IE=8"/>[/ruby:1chqwlqg]. Note that this meta tag should be placed at the top of the [ruby:1chqwlqg]<head>[/ruby:1chqwlqg] tag.
Beware that the user agent string will still report [ruby:1chqwlqg]MSIE 7.0[/ruby:1chqwlqg] for embedded WebBrowsers - even though you use IE8 mode. This differs from when you test the same HTML in the normal web browser where it returns [ruby:1chqwlqg]MSIE 8.0[/ruby:1chqwlqg]. To check the rendering mode: [ruby:1chqwlqg]document.documentMode[/ruby:1chqwlqg].
HTML, CSS and Javascript
Personally I use Strict DOCTYPE as it render more consistently between platform.To simplify javascript work I use jQuery which is a lightweight framework that let you quickly manipulate the DOM and deal with events in a manner where you don't have to concern yourself much about differences between the platforms.
For in introduction to HTML and CSS I recommend HTML Dog. It's up to date and will recommend best practices. http://htmldog.com/
For lookup references to most web related languages: http://www.w3schools.com/
The ultimate reference to web standards: http://www.w3.org/
WebDialog.new
You can specify the arguments as either a comma separated list, or as a single Hash object. Currently the manual is missing information for both of these.Comma Separated Arguments
- [ruby:1chqwlqg]dialog_title[/ruby:1chqwlqg] The title to be displayed in the webdialog.
- [ruby:1chqwlqg]scrollable[/ruby:1chqwlqg] true if you want to allow scrollbars, false if you do not want to allow scrollbars.
- [ruby:1chqwlqg]pref_key[/ruby:1chqwlqg] The registry entry where the location and size of the dialog will be saved. If preferences_key is not included, the location and size will not be stored.
- [ruby:1chqwlqg]width[/ruby:1chqwlqg] The width of the webdialog.
- [ruby:1chqwlqg]height[/ruby:1chqwlqg] The height of the webdialog.
- [ruby:1chqwlqg]left[/ruby:1chqwlqg] The number of pixels from the left.
- [ruby:1chqwlqg]top[/ruby:1chqwlqg] The number of pixels from the top.
- [ruby:1chqwlqg]resizable[/ruby:1chqwlqg] true if you want to allow the window to be resize by the user.
Hash argument
keys = { ;dialog_title => title, ;scrollable => false, ;preferences_key => 'MyDialog', ;height => 300, ;width => 400, ;left => 200, ;top => 200, ;resizable => true, ;mac_only_use_nswindow => true} @dialog = UI;;WebDialog.new(keys)
But the hash exposes a new undocumented argument, [ruby:1chqwlqg]:mac_only_use_nswindow[/ruby:1chqwlqg].
Fixed window size
When you specify position and size Sketchup only uses those values the first time you create the dialog. After that it reads the last used values from the registry. That might be want to you want for resizable windows. But maybe not for windows with a fixed size which the user can't resize.When you develop a plugin you might find that you need to change the size of your fixed size window, but you can't see the effect because Sketchup just reads your last values. In which case you need to delete the registry settings for your Webdialog, or use the [ruby:1chqwlqg].set_size[/ruby:1chqwlqg] method after you create the fixed size window to ensure the correct size.
And if you do not specify a preference key, Sketchup seem to disregard both size and position.
Scrollbars
The scrollbar argument does not seem to work on PC. In order to disable the scrollbars you must set a CSS property. What HTML to assign this property to depends if your HTML uses Quirks Mode or Standards Mode.If you're using Quicks Mode you assign it to the BODY element:
[ruby:1chqwlqg]body { overflow: hidden; }[/ruby:1chqwlqg]If you are using Standard Mode you assign it to the HTML element:
[ruby:1chqwlqg]html { overflow: hidden; }[/ruby:1chqwlqg]This is because the effective root element in an HTML document differs from Quicks to Standards Mode.
Paths - WebDialog.set_file vs WebDialog.set_html
When you use.set_file
to populate the HTML document, all resources (images,CSS,scripts etc.) will be relative to the file you specify.But when you use
.set_html
, all resources are relative to a temp file created on the system. So if you need to reference external resources from the HTML, either use absolute paths, or add a [ruby:1chqwlqg]<base>[/ruby:1chqwlqg] tag to the [ruby:1chqwlqg]<head>[/ruby:1chqwlqg] of the [ruby:1chqwlqg]<html>[/ruby:1chqwlqg] - specifying where relative paths should be resolved from:
[ruby:1chqwlqg]<base href="c:/absolute/path/" />[/ruby:1chqwlqg]Bugs and Issues
OSX .execute_script and quotes
There was some issues with.execute_script
and quotes in Sketchup prior to 7.0 on OSX. http://forums.sketchucation.com/viewtopic.php?f=180&t=8316#p49259WebDialog Javascript callback Maximum message size
The Javascript callback to ruby has a size limitation. When sending data back to ruby it's better to store the data in a hidden input field and use [ruby:1chqwlqg].get_element_value[/ruby:1chqwlqg]. http://forums.sketchucation.com/viewtopic.php?f=180&t=8683#p52107#<Exception: Invalid Dialog>
Unknown error. Caused by BoundingBox? http://forums.sketchucation.com/viewtopic.php?f=180&t=22567#p190035<LocalJumpError: return from proc-closure> in WebDialog
Issues with using r[ruby:1chqwlqg]eturn[/ruby:1chqwlqg] in callback methods from Javascript? Think I've experience this myself. http://forums.sketchucation.com/viewtopic.php?f=180&t=22022#p185099Debugging
You can use Firebug Lite to help debugging your HTML+JS in WebDialogs.
http://getfirebug.com/lite.htmlThanks
Thanks to everyone on SCF that has contributed with their share of this collective knowledge.
-
-
greatly appreciated!
-
Note to self: Update Async vs sync Communication
It's not.execute_script
that's async - it's the Javascript callback using theskp:
protocol -
Thanks for doing this Thomas.
-
Revision 1
Updated info about async vs sync behaviour. -
-
@unknownuser said:
Finally, there is a difference in the way that the Mac boots up SketchUp that you should be cautious about: there is no Sketchup.active_model when the Ruby scripts are first loaded. So if your script is making changes to the active_model at load time, it will not work on the Mac. The answer? Ensure code that references the active model is part of a UI event handler, responding to the user selecting a tool or a menu item. You can also use an AppObserver to get a callback whenever a new model is opened, at which point it's safe to talk to the active_model.
I didn't see this anywhere. I don't remember where it comes from.
How about marking topics and posts with [WebDialog]?
Good work - most generous with your time.
Chris
-
I hope that people will point out things that are not clear. Writing has never been my strongest skill, actually - its one of my poor, so please point out the weaknesses.
-
Thank you!
-
Hi Thom,
thanks for sharing this really usefull information!
Just as a side note:
We have found a bug, which cuts decimal value sent from SketchUp to WebDialog (only in SU6 on Mac). If we i.e. want to update the value of some input box like this:
web_dialog.execute_script("updateInputBox('varName', '12,345')")
only 12 is shown in the varnName inputbox, everything behind (and including) comma is being cut off. But it works in SU7 on Mac and on both, 6 and 7 versions of SU on Windows. -
Ah, is that whatæs being mentioned in the release notes: http://code.google.com/apis/sketchup/docs/releases.html
@unknownuser said:
Fixed Mac support for WebDialogs execute_script
WebDialog.execute_script('alert("Bug is Fixed!")');
Does it work if you escape the comma? If not, replace it with another character?
-
No, escaping doesn't seem to help. Only way to pass the float value is to write it using dot (1.12) not comma (1,12)...
For now we have not found a workaround, but we intend to make some more tests to see if the problem can be bypassed. -
I wonder, if you make a special receiving javascript function, and send all command base64 encoded to that function and have it decode and eval it..?
# made up methods - haven't checked the real methods jscall = base64encode("updateInputBox('varName', '12,345')") WebDialog.execute_script("decode(#{jscall})");
function decode(base64str) eval(decode64(base64str)); end
-
-
You won't be able to use HTML5 in webdialogs - not until IE adds support for it. Think I read somewhere that they where adding support for it in IE9. Being able to use CANVAS sure would be nice.
-
@thomthom said:
You won't be able to use HTML5 in webdialogs - not until IE adds support for it.
I am using excanvas http://code.google.com/p/explorercanvas/ which provides a canvas object in IE.
Thomas
-
@tbleicher said:
@thomthom said:
You won't be able to use HTML5 in webdialogs - not until IE adds support for it.
I am using excanvas http://code.google.com/p/explorercanvas/ which provides a canvas object in IE.
Thomas
That's very interesting! I've been wanting for a good solution to dynamically draw graphics in webdialogs. Probably be of interest for Whaat as well... ...thinking Profile Builder...
-
And just to have more options, there is also chrome frame.
-
@jim said:
And just to have more options, there is also chrome frame.
Yea, but this requires the user to install a browser plugin.
explorercanvas is a simple JS library which the developer includes in the project without the user ever having to install any browser extension. That's what's appeal to me. -
this seems to be very interesting
Have to dig into this.
Advertisement