-
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
Changes from 9 commits
887da68
cdd3350
73534fe
7db0785
3e710ed
a678381
0914c4f
1871b93
880ad06
ca39c8d
9711de3
e034277
9ed3838
f90f1c7
d73a373
405ae66
25d82eb
bbc7df6
d89ffbe
7f5398b
388d463
e7685da
3a4a4a9
ec62839
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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({ | ||
|
@@ -110,6 +111,8 @@ require({ | |
if (!defined(window.Cesium)) { | ||
window.Cesium = Cesium; | ||
} | ||
// Used by Sandcastle-helpers.js | ||
window.pako = pako; | ||
|
||
parser.parse(); | ||
|
||
|
@@ -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]; | ||
|
@@ -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) { | ||
|
@@ -620,7 +607,7 @@ 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); | ||
} | ||
}; | ||
|
@@ -775,20 +762,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 { | ||
|
@@ -953,10 +930,7 @@ require({ | |
return location.protocol + '//' + location.host + location.pathname; | ||
} | ||
|
||
registry.byId('buttonShareDrop').on('click', function() { | ||
var code = jsEditor.getValue(); | ||
var html = htmlEditor.getValue(); | ||
|
||
function makeCompressedBase64String(html, code) { | ||
// 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]); | ||
|
@@ -965,6 +939,15 @@ require({ | |
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(html, code); | ||
|
||
var shareUrlBox = document.getElementById('shareUrl'); | ||
shareUrlBox.value = getBaseUrl() + '#c=' + base64String; | ||
shareUrlBox.select(); | ||
|
@@ -1019,7 +1002,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'; | ||
|
@@ -1044,25 +1027,21 @@ 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. | ||
emackey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? |
||
|
||
window.open(url, '_blank'); | ||
window.focus(); | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/*global pako*/ | ||
(function() { | ||
'use strict'; | ||
|
||
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]; | ||
|
||
return { | ||
code : code, | ||
html : html | ||
}; | ||
}; | ||
}()); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<!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="Sandcastle-helpers.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"> | ||
if(typeof require === 'function') { | ||
var urlParams = new URLSearchParams(window.location.search); | ||
|
||
if (urlParams.has('gallery')) { | ||
var galleryPath = urlParams.get('gallery'); | ||
document.head.innerHTML = document.head.innerHTML + '<base href="' + galleryPath + '" />'; | ||
} | ||
|
||
require.config({ | ||
baseUrl : '../../../', | ||
waitSeconds : 120 | ||
}); | ||
} | ||
</script> | ||
</head> | ||
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html"> | ||
<script type="text/javascript"> | ||
/*global pako,decodeBase64Data,embedInSandcastleTemplate */ | ||
if (typeof require === 'function') { | ||
require([ | ||
'Source/Cesium' | ||
], function( | ||
Cesium) { | ||
'use strict'; | ||
window.Cesium = Cesium; | ||
loadDemoFromUrl(); | ||
}); | ||
} else { | ||
loadDemoFromUrl(); | ||
} | ||
|
||
function loadDemoFromUrl() { | ||
'use strict'; | ||
// The helper functions script needs this. | ||
window.pako = pako; | ||
var defined = Cesium.defined; | ||
var loaderElement; | ||
var frameDelay = 30; | ||
var code; | ||
//Handle case where demo is in a sub-directory by modifying | ||
//the HTML to add a base href. | ||
var urlParams = new URLSearchParams(window.location.search); | ||
|
||
function update() { | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. spacing |
||
if (frameDelay <= 0) { | ||
done = true; | ||
var scriptElement = document.createElement('script'); | ||
var isFirefox = navigator.userAgent.indexOf('Firefox/') >= 0; | ||
document.head.appendChild(scriptElement); | ||
scriptElement.innerHTML = embedInSandcastleTemplate(code, isFirefox); | ||
} | ||
} | ||
|
||
if (!done) { | ||
requestAnimationFrame(update); | ||
} | ||
} | ||
|
||
if (window.location.hash.indexOf('#c=') === 0) { | ||
var base64String = window.location.hash.substr(3); | ||
var data = decodeBase64Data(base64String); | ||
var html = data.html; | ||
code = data.code; | ||
// Replace CSS URL since standalone is one level up from the usual bucket.html | ||
if (!urlParams.has('gallery')) { | ||
html = html.replace('../templates', 'templates'); | ||
} | ||
html += '<div id="loader"></div>'; | ||
html += '<style>#loader { width : 12px }</style>'; | ||
|
||
// Add the HTML content | ||
var htmlElement = document.createElement('div'); | ||
htmlElement.innerHTML = html; | ||
document.body.appendChild(htmlElement); | ||
// Add the JavaScript only when CSS has loaded | ||
loaderElement = document.querySelector('#loader'); | ||
|
||
requestAnimationFrame(update); | ||
} | ||
} | ||
</script> | ||
</body> | ||
</html> |
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?