-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create Sandcastle Standalone Mode #7250
Conversation
Thanks for the pull request @OmarShehata!
Reviewers, don't forget to make sure that:
I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome. 🌍 🌎 🌏 |
Interesting approach here! I think it's an improvement over the existing system. One downside is that I used to always use "open in new window" to get the Sandcastle code into the top-level frame, for easier debugging. Yeah I know that the user can pick the "bucket.html" frame from a drop-down in the console, but, sometimes putting your own code in the top frame just makes life easier for debugging. With that in mind, does The ideal situation I'm trying to replicate is what happens when you right-click a gallery item thumbnail and say "open in new tab", and it loads the gallery item directly into the top frame. That method doesn't work for hashes, of course, but it seems like it should be able to do something similar, loading the bucket at the top and injecting the hash's code. |
That's exactly the approach I started with, and I agree that would be much nicer. I had to start stripping down Part of it is my unfamiliarity with how Sandcastle dynamically loads and runs demos. If all we need to run the demo is to put the bucket in a div on the page, what's the iframe currently there for? |
The iframe is just there to keep the inner workings of the demo fully separate from the inner workings of the Sandcastle editing environment. Your demo can damage the DOM or the global state inside the iframe and then reload from scratch without losing your work-in-progress in Sandcastle. The demo's global CSS styles are likewise firewalled away from Sandcastle's editor and toolbar. No need for any of these protections when opening a separate window. So I think So, my thinking is:
|
@emackey I was halfway through implementing this new architecture when I realized I was getting an error when adding the script tag before the HTML (because it was executing immediately). Which meant I didn't really need to do the This works in Chrome, Edge, Firefox and IE11. This means we can just:
And that's it. Am I missing anything here? I'll clean this up and push it in the next few hours. |
Sounds great! |
Ok, I've finished refactoring this. It's a lot simpler now, and definitely feels a lot faster I think without all the baggage of dojo/dijit in the new window! I abstracted away a couple functions in
Did not work (because that file needs require). I had a bit of a revelation while working on this: I was getting the old Sandcastle CSS issue #5265 very consistently when adding the HTML first and then the JavaScript. Using the MutationObserver didn't actually work because waiting for the DOM element to be added wasn't enough, it seemed like it still had to load. I realized that just listening for:
Works perfectly. Which makes me wonder if that would just be a better way to do it in But for now, this should be clean and working. Let me know how this looks @emackey . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great approach. Found one minor path issue, but I have a bigger problem: On my machine, the load
event has already fired before the code sets up the callback. So I end up stuck on the "Loading..." screen indefinitely, and the script never loads. Win 10, Chrome, both NodeJS and IIS servers. No idea why.
Ok, so I was only able to recreate this on Firefox. Turns out the There's no robust way to check for if the CSS has finished loading. Best I could find was this trick of declaring some CSS, and checking for when it has been applied in a loop. This now works on all the browsers I could find. Can you give it another try @emackey ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really awesome improvement. There's one weird edge case with paths in the "development" subfolder. Not sure what the best solution is, but I've never liked having those demos be a level down from others. Maybe they could move up to a "devGallery" or such alongside the main gallery, at the same path depth. Not sure, just an idea. Would like to see this get merged soon.
Ok, @emackey , it's not the ideal solution (which I think would be just flattening everything in one folder and using the I'm not very familiar with running the development examples, but it should be working now for development and normal examples. |
Adjust relative paths
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we try IE11? (I'm on Linux right now so I can't test) |
Apps/Sandcastle/standalone.html
Outdated
var width = getComputedStyle(loaderElement).getPropertyValue('width'); | ||
var done = false; | ||
if (width === '12px') { | ||
frameDelay --; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spacing
Why is |
Apps/Sandcastle/CesiumSandcastle.js
Outdated
@@ -110,6 +111,8 @@ require({ | |||
if (!defined(window.Cesium)) { | |||
window.Cesium = Cesium; | |||
} | |||
// Used by Sandcastle-helpers.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why doesn't sandcastle-helpers use AMD syntax and include pako itself?
This does not appear to work at all with the built version of Sandcastle. |
Just tried IE11, it appears broken there as well (first it identified the click as a pop-up, but then I allowed popups and it still failed (or seemed to hang?) |
Apps/Sandcastle/CesiumSandcastle.js
Outdated
window.open(htmlBlobURL, '_blank'); | ||
var data = makeCompressedBase64String(htmlEditor.getValue(), jsEditor.getValue()); | ||
var url = getBaseUrl(); | ||
url = url.replace('index.html','') + 'standalone.html' + '?gallery=' + baseHref + '#c=' + data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
baseHref needs to be url encoded (that might be why it's broken on IE). query parameters need to be encoded with sandcastle-helpers
(but as with my other comment, this shouldn't be a query parameter then it doesn't matter)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we're sending an absolute url either, couldn't this just be relative to the current Sandcastle root?
Ok, good news. I added a "compile bucket.css" step (f90f1c7) in the build process, which correctly fixes the CSS race conditions both in standlone and in the regular Sandcastle. It also greatly simplifies I tested all the combinations of built, unbuilt, for regular and development examples, for Chrome, Edge, IE11 and Firefox. The only issue with IE11 is when the URL is too long. I spent too long trying to get @emackey do you mind testing it one last time? |
Update |
This all sounds good to me. Not sure about @emackey can you do the final test/merge here? I don't have access to IE11 at the moment and you know this code a lot better than me. Thanks. (And thanks again @OmarShehata sorry for the delay) |
@mramato thanks for the review! I'll address your suggestions. For the naming, I remember doing this because I thought it otherwise wouldn't be backwards compatible (since all the Sandcastles in the wild will try to import |
That sounds like a good reason, but @emackey may know better. |
I made sure the generated bucket css gets removed on |
What happened with Travis CI?
Correct. Overall this looks good. It no longer works in my IIS subfolder, but seems to work fine when used with |
This doesn't sounds right. Why doesn't it work under IIS? This shouldn't have a server component at all since it needs to work out of S3 as well. |
Travis is probably failing due to #7249. I restarted the build. It does work for me when served from a simple static server (with |
There are absolute paths involved, or relative paths that go "too high". I serve Cesium out of a I spent a while this morning trying to narrow down exactly where the problem is. It affects the "open in new window" feature of both built and non-built Sandcastle, with different errors for each. |
That definitely sounds like something we should fix before merging this, because it means our deployed branches won't work either. |
@OmarShehata Try launching your python server in the parent folder, above the Cesium source tree. |
gulpfile.js
Outdated
var standaloneStream = gulp.src([ | ||
'Apps/Sandcastle/standalone.html' | ||
]) | ||
.pipe(gulpReplace('../../ThirdParty/requirejs-2.1.20/require.js', '/Build/CesiumUnminified/Cesium.js')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's one suspect path. It looks server-root-relative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay yeah, I can recreate it locally now.
Ok so this was the issue:
from #7250 (comment) This wasn't an issue for regular Sandcastle because it was still using I've tested it on every combination of browser (IE11, Firefox and Chrome), built/unbuilt, hosted out of |
Just to confirm. With your changes, is the built version of Sandcastle using the built version of Cesium? Or is "Open in new Window" always using the built version? What is the exact behavior here. The most important thing is that "Open in New Window" or Standalone mode uses the built version (either in all cases if it has to be that way, or at least when using the built Sandcastle) |
Sandcastle itself hasn't changed. It uses What I meant by:
Was that even though built Sandcastle uses the built version of Cesium, it still includes some modules from |
This works for me in IIS 👍 |
One last thing, update CHANGES |
@mramato I thought we don't put Sandcastle changes in CHANGES (#7152 (comment)). There's no change to the CesiumJS API here. |
That comment was regarding breaking changes, which for the most part don't apply to Sandcastle, we do mention new examples or functionality in Sandcastle when it happens. In this case it also fixes a bug because Open in New Window used to not work in many cases and also couldn't allow you to share the url, right? |
Makes sense. Should be ready now! |
This is attempt 2 to create a standalone Sandcastle model. This is the previous attempt #7097.
@hpinkos @mramato what do you think?
This is a refactor in that it works exactly the same way from the user's prespective. Any Sandcastle URL like:
Can be run in "standalone" mode by adding
standalone.html
:This will work regardless if the demo is loaded from the gallery, from a custom base64 string, or from a GitHub gist (and whatever else Sandcastle does that I am not aware of).
It also opens this mode instead of the blob URL when clicking "Open in new window" button. This fixes that button (which currently will not load ion imagery) as well as creating a way to view Sandcastle examples on mobile.
And best of all, it's a completely client side solution!
The only catch is it's kind of a hack. The standalone mode is actually just the same Sandcastle page with everything hidden and a few HTML edits. Ideally we'd have a responsive view but we don't, and this is the next best thing.
What is nice about this is that there's nothing to maintain. It's the exact same behavior/code.
Can standalone.html just be index.html with a query parameter?
Yeah but then it won't hide elements until JavaScript runs which will cause a very visible jitter and look ugly.