Sandcastle: Cesium & viewer vars

In the browser console (not the sandcastle console at the bottom) Cesium and viewer are both undefined. I assume because they are encapsulated somehow. Is it possible to access these from the browser console and outside scripts?

They’re not accessible because the Cesium scene is running in an iframe. What I’ve done to get around this is just use the “Open in new window”, which will load the same Sandcastle without an iframe.

Thanks for the info. Hmm, I haven’t tried yet, but one of the answers here looks promising (without having to open in new window.)
stackoverflow.com/questions/13757943/access-a-variable-of-iframe-from-parent
Using contentWindow instead of contentDocument
So maybe something like this in the included scripts:

var Cesium = document.getElementById("iframeid").contentWindow.Cesium;

I was thinking that domain match shouldn’t be an issue, as the parent frame is in the same domain as the iframe, regardless of where it downloads the script data from that it requests, though I could be wrong.

I think I’ve found the iframe: id=“bucketFrame”
When I open that up using the browser dev tools I see src="…/Sandcastle-client.js"

In dev tools console, when you select top from drop-down box this works:
document.getElementById(“bucketFrame”).contentWindow.Cesium;

In dev tools console, when you select bucketFrame from drop-down box this works:
Cesium

Half way there. I still can’t seem to access viewer, even after running the var viewer = line. Cesium was already defined before pressing run I presume. I hope the code typed in the text box is accessible as well.

I see a script within the body of the iframe, and within I see the code typed into the text box. It is within a function startup(Cesium) and is within 2 comments:
//Sandcastle_begin
var viewer = new Cesium.Viewer(“cesiumContainer”);
//Sandcastle_end
That startup function written by window.embedInSandcastleTemplate = function (code, addExtraLine)

I wonder if there’s a way to get at the variables within that function.
document.getElementById(“bucketFrame”).contentWindow.Sandcastle
seems promising, but no luck finding the viewer var.

I didn’t know about the contentWindow trick. So all you’d have to do then is make the viewer and Cesium available from within the Sandcastle:

var viewer = new Cesium.Viewer("cesiumContainer");
window.viewer = viewer;
window.Cesium = Cesium;

And then in the browser console you could do:

// Get the instance of Cesium
var Cesium = document.querySelector("#bucketFrame").contentWindow.Cesium;

And then for example make the camera fly somewhere:

document.querySelector("#bucketFrame").contentWindow.viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(10, 10, 1000)
});

You don’t seem to need window.Cesium as it appears to be already accessible via
document.getElementById(“bucketFrame”).contentWindow.Cesium

However you seemed to have solved the problem of getting access to viewer with ‘window.viewer=viewer’ from within the textbox code!

Without 'window.viewer=viewer (from top page, not iframe)
document.getElementById(“bucketFrame”).contentWindow.viewer
fails, undefined

With 'window.viewer=viewer (from top page, not iframe)
document.getElementById(“bucketFrame”).contentWindow.viewer
works!

I’m gonna see if I can finally get my plugin to work in remote sandcastle instances with these new discoveries.

EDIT: making progress, I’ve got portions of my plugin working in a remote sandcastle.
EDIT2: shazam, working totally, I just copy/paste a few lines of code and I can use my plugin in any remote sandcastle. Thanks for the tip of window.viewer=viewer, that was key!

1 Like

If you’re running in Chrome, I recently discovered that the dev tools let you switch context on the fly with this nifty button:

1 Like

At first I thought that the include libraries would be loaded at the top level so I thought I’d need to use the contentWindow property. Turns out that it loaded to the iframe bucketFrame (makes sense as they are invoked from there) so there was no need. The main thing was exposing the viewer var (which appears to be encapsulated) to the window, that was key to making it work.