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!
If youâre running in Chrome, I recently discovered that the dev tools let you switch context on the fly with this nifty button:
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.