Skip to content
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

Merged
merged 24 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Thumbs.db

/Apps/Sandcastle/jsHintOptions.js
/Apps/Sandcastle/gallery/gallery-index.js
/Apps/Sandcastle/templates/bucket.css

/Source/Cesium.js

Expand Down
105 changes: 33 additions & 72 deletions Apps/Sandcastle/CesiumSandcastle.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*global require,Blob,JSHINT*/
/*global require,Blob,JSHINT */
/*global decodeBase64Data, embedInSandcastleTemplate */
/*global gallery_demos, has_new_gallery_demos, hello_world_index*/// defined in gallery/gallery-index.js, created by build
/*global sandcastleJsHintOptions*/// defined by jsHintOptions.js, created by build
require({
Expand Down Expand Up @@ -103,6 +104,8 @@ require({
pako) {
'use strict';

window.pako = pako; // For Sandcastle-helpers.

// attach clipboard handling to our Copy button
var clipboardjs = new ClipboardJS('.copyButton');

Expand Down Expand Up @@ -383,7 +386,7 @@ require({
// make a copy of the options, JSHint modifies the object it's given
var options = JSON.parse(JSON.stringify(sandcastleJsHintOptions));
/*eslint-disable new-cap*/
if (!JSHINT(getScriptFromEditor(false), options)) {
if (!JSHINT(embedInSandcastleTemplate(jsEditor.getValue(), false), options)) {
var hints = JSHINT.errors;
for (i = 0, len = hints.length; i < len; ++i) {
var hint = hints[i];
Expand Down Expand Up @@ -540,22 +543,6 @@ require({
}
});

function getScriptFromEditor(addExtraLine) {
return 'function startup(Cesium) {\n' +
' \'use strict\';\n' +
'//Sandcastle_Begin\n' +
(addExtraLine ? '\n' : '') +
jsEditor.getValue() +
'//Sandcastle_End\n' +
' Sandcastle.finishedLoading();\n' +
'}\n' +
'if (typeof Cesium !== \'undefined\') {\n' +
' startup(Cesium);\n' +
'} else if (typeof require === \'function\') {\n' +
' require([\'Cesium\'], startup);\n' +
'}\n';
}

var scriptCodeRegex = /\/\/Sandcastle_Begin\s*([\s\S]*)\/\/Sandcastle_End/;

function activateBucketScripts(bucketDoc) {
Expand All @@ -578,6 +565,7 @@ require({
// Apply user HTML to bucket.
var htmlElement = bucketDoc.createElement('div');
htmlElement.innerHTML = htmlEditor.getValue();
bucketDoc.body.appendChild(htmlElement);

var onScriptTagError = function() {
if (bucketFrame.contentDocument === bucketDoc) {
Expand Down Expand Up @@ -620,34 +608,12 @@ require({
// Firefox line numbers are zero-based, not one-based.
var isFirefox = navigator.userAgent.indexOf('Firefox/') >= 0;

element.textContent = getScriptFromEditor(isFirefox);
element.textContent = embedInSandcastleTemplate(jsEditor.getValue(), isFirefox);
bucketDoc.body.appendChild(element);
}
};
// If we just add `htmlElement` to the DOM and run
// loadScript(), there's a chance it will inject CSS
// before the HTML content is fully loaded, leading to a broken page.
// So instead we create an observer instance to watch for when
// the element has been added.
// See https://github.com/AnalyticalGraphicsInc/cesium/issues/5265
var observer = new MutationObserver(function (mutationsList) {
// See https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
var length = mutationsList.length;
for (var i = 0; i < length; i++) {
var mutation = mutationsList[i];
// Watch for an element with the data-sandcastle-loaded attribute.
if (defined(mutation.target.dataset) && mutation.target.dataset.sandcastleLoaded === 'yes') {
loadScript();
observer.disconnect();
}
}
});

// Start observing the target node for configured mutations
var config = { attributes: true, childList: true, subtree: true };
observer.observe(bucketDoc, config);

bucketDoc.body.appendChild(htmlElement);
loadScript();
}

function applyBucket() {
Expand Down Expand Up @@ -775,20 +741,10 @@ require({

applyLoadedDemo(code, html);
} else if (window.location.hash.indexOf('#c=') === 0) {
// data stored in the hash as:
// Base64 encoded, raw DEFLATE compressed JSON array where index 0 is code, index 1 is html
var base64String = window.location.hash.substr(3);
// restore padding
while (base64String.length % 4 !== 0) {
base64String += '=';
}
var jsonString = pako.inflate(atob(base64String), { raw: true, to: 'string' });
// we save a few bytes by omitting the leading [" and trailing "] since they are always the same
jsonString = '["' + jsonString + '"]';
json = JSON.parse(jsonString);
// index 0 is code, index 1 is html
code = json[0];
html = json[1];
var data = decodeBase64Data(base64String);
code = data.code;
html = data.html;

applyLoadedDemo(code, html);
} else {
Expand Down Expand Up @@ -953,18 +909,24 @@ require({
return location.protocol + '//' + location.host + location.pathname;
}

registry.byId('buttonShareDrop').on('click', function() {
var code = jsEditor.getValue();
var html = htmlEditor.getValue();

function makeCompressedBase64String(data) {
// data stored in the hash as:
// Base64 encoded, raw DEFLATE compressed JSON array where index 0 is code, index 1 is html
var jsonString = JSON.stringify([code, html]);
var jsonString = JSON.stringify(data);
// we save a few bytes by omitting the leading [" and trailing "] since they are always the same
jsonString = jsonString.substr(2, jsonString.length - 4);
var base64String = btoa(pako.deflate(jsonString, { raw: true, to: 'string', level: 9 }));
base64String = base64String.replace(/\=+$/, ''); // remove padding

return base64String;
}

registry.byId('buttonShareDrop').on('click', function() {
var code = jsEditor.getValue();
var html = htmlEditor.getValue();

var base64String = makeCompressedBase64String([code, html]);

var shareUrlBox = document.getElementById('shareUrl');
shareUrlBox.value = getBaseUrl() + '#c=' + base64String;
shareUrlBox.select();
Expand Down Expand Up @@ -1019,7 +981,7 @@ require({
return local.headers + '\n' +
htmlEditor.getValue() +
'<script id="cesium_sandcastle_script">\n' +
getScriptFromEditor(false) +
embedInSandcastleTemplate(jsEditor.getValue(), false) +
'</script>\n' +
'</body>\n' +
'</html>\n';
Expand All @@ -1044,25 +1006,24 @@ require({
});

registry.byId('buttonNewWindow').on('click', function() {
//Handle case where demo is in a sub-directory by modifying
//the demo's HTML to add a base href.
var baseHref = window.location.href;

//Handle case where demo is in a sub-directory.
var searchLen = window.location.search.length;
if (searchLen > 0) {
baseHref = baseHref.substring(0, baseHref.length - searchLen);
}

var pos = baseHref.lastIndexOf('/');
baseHref = baseHref.substring(0, pos) + '/gallery/';

var html = getDemoHtml();
html = html.replace('<head>', '<head>\n <base href="' + baseHref + '">');
var htmlBlob = new Blob([html], {
'type' : 'text/html;charset=utf-8',
'endings' : 'native'
});
var htmlBlobURL = URL.createObjectURL(htmlBlob);
window.open(htmlBlobURL, '_blank');
var code = jsEditor.getValue();
var html = htmlEditor.getValue();
var data = makeCompressedBase64String([code, html, baseHref]);

var url = getBaseUrl();
url = url.replace('index.html','') + 'standalone.html' + '#c=' + data;

window.open(url, '_blank');
window.focus();
});

Expand Down
41 changes: 41 additions & 0 deletions Apps/Sandcastle/Sandcastle-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(function() {
'use strict';
var pako = window.pako;

window.embedInSandcastleTemplate = function(code, addExtraLine) {
return 'function startup(Cesium) {\n' +
' \'use strict\';\n' +
'//Sandcastle_Begin\n' +
(addExtraLine ? '\n' : '') +
code +
'//Sandcastle_End\n' +
' Sandcastle.finishedLoading();\n' +
'}\n' +
'if (typeof Cesium !== \'undefined\') {\n' +
' startup(Cesium);\n' +
'} else if (typeof require === \'function\') {\n' +
' require([\'Cesium\'], startup);\n' +
'}\n';
};
window.decodeBase64Data = function(base64String) {
// data stored in the hash as:
// Base64 encoded, raw DEFLATE compressed JSON array where index 0 is code, index 1 is html
// restore padding
while (base64String.length % 4 !== 0) {
base64String += '=';
}
var jsonString = pako.inflate(atob(base64String), { raw: true, to: 'string' });
// we save a few bytes by omitting the leading [" and trailing "] since they are always the same
jsonString = '["' + jsonString + '"]';
var json = JSON.parse(jsonString);
// index 0 is code, index 1 is html
var code = json[0];
var html = json[1];
var baseHref = json[2];
return {
code : code,
html : html,
baseHref : baseHref
};
};
}());
1 change: 1 addition & 0 deletions Apps/Sandcastle/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

<script src="jsHintOptions.js"></script>
<script src="gallery/gallery-index.js"></script>
<script type="text/javascript" src="Sandcastle-helpers.js"></script>
<script src="CesiumSandcastle.js"></script>
<!-- Needed for autocomplete -->
<link rel="stylesheet" href="../../ThirdParty/codemirror-4.6/addon/hint/show-hint.css">
Expand Down
74 changes: 74 additions & 0 deletions Apps/Sandcastle/standalone.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Cesium Demo</title>
<script type="text/javascript" src="Sandcastle-header.js"></script>
<script type="text/javascript" src="Sandcastle-client.js"></script>
<script type="text/javascript" src="ThirdParty/pako.min.js"></script>
<script type="text/javascript" src="../../ThirdParty/requirejs-2.1.20/require.js"></script>
<script type="text/javascript" src="Sandcastle-helpers.js"></script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<script type="text/javascript">
/*global pako */
if (window.location.hash.indexOf('#c=') === 0) {
var base64String = window.location.hash.substr(3);
var data = window.decodeBase64Data(base64String);
//Handle case where demo is in a sub-directory by modifying
//the HTML to add a base href.
document.head.innerHTML = document.head.innerHTML + '<base href="' + data.baseHref + '" />';
window.sandcastleData = data;
}

require({
baseUrl : '../../../',
waitSeconds : 120,
packages: [{
name: 'CesiumUnminified',
location: '../Build/CesiumUnminified',
main: 'Cesium'
}]
},[
'Source/Cesium'
], function(
Cesium) {
'use strict';
if (window.Cesium === undefined) {
window.Cesium = Cesium;
}

// The helper functions script needs this.
window.pako = pako;

var defined = window.Cesium.defined;
var code;

if (defined(window.sandcastleData)) {
var base64String = window.location.hash.substr(3);
var data = window.sandcastleData;
var html = data.html;
code = data.code;
var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
if (isIE11) {
html = html.replace('../templates', 'templates');
}

// Add the HTML content
var htmlElement = document.createElement('div');
htmlElement.innerHTML = html;
document.body.appendChild(htmlElement);

// Add the JavaScript
var scriptElement = document.createElement('script');
var isFirefox = navigator.userAgent.indexOf('Firefox/') >= 0;
document.head.appendChild(scriptElement);
scriptElement.innerHTML = window.embedInSandcastleTemplate(code, isFirefox);
}
});

</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ body {
padding: 4px;
border: 1px solid #444;
border-radius: 4px;
}
}
5 changes: 3 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Change Log
* Fixed an issue where classification primitives with the `CESIUM_3D_TILE` classification type would render on terrain. [#7422](https://github.com/AnalyticalGraphicsInc/cesium/pull/7422)
* Fixed an issue where 3D Tiles would show through the globe. [#7422](https://github.com/AnalyticalGraphicsInc/cesium/pull/7422)
* Fixed crash when entity geometry show value is an interval that only covered part of the entity availability range [#7458](https://github.com/AnalyticalGraphicsInc/cesium/pull/7458)
* Fix rectangle positions at the north and south poles [#7451](https://github.com/AnalyticalGraphicsInc/cesium/pull/7451)
* Fixed image size issue when using multiple particle systems [#7412](https://github.com/AnalyticalGraphicsInc/cesium/pull/7412)
* Fix rectangle positions at the north and south poles. [#7451](https://github.com/AnalyticalGraphicsInc/cesium/pull/7451)
* Fixed image size issue when using multiple particle systems. [#7412](https://github.com/AnalyticalGraphicsInc/cesium/pull/7412)
* Fixed Sandcastle's "Open in New Window" button not displaying imagery due to blob URI limitations. [#7250](https://github.com/AnalyticalGraphicsInc/cesium/pull/7250)

### 1.53 - 2019-01-02

Expand Down
Loading