Compare commits

...

6 Commits

Author SHA1 Message Date
jjspace 1bd2c0e780
Merge d8a7e22f04 into 673bd6a82f 2025-11-26 09:16:47 +08:00
Marco Hutter 673bd6a82f
Merge pull request #13026 from CesiumGS/fix-sandcastle-paths
deploy / deploy (push) Waiting to run Details
dev / lint (push) Waiting to run Details
dev / coverage (push) Waiting to run Details
dev / release-tests (push) Waiting to run Details
dev / node-20 (push) Waiting to run Details
sandcastle-dev / deploy (push) Waiting to run Details
Fix Sandcastle paths for windows
2025-11-26 00:10:13 +00:00
jjspace 0b11c10039
Merge remote-tracking branch 'origin/main' into fix-sandcastle-paths 2025-11-25 12:54:17 -05:00
jjspace 2171604b40
use node executable for windows 2025-11-25 12:50:55 -05:00
jjspace d8a7e22f04
wait for code to load 2025-11-25 12:27:17 -05:00
jjspace 841a4cf12a
better tsc path and fix globby paths for windows 2025-11-07 17:20:46 -05:00
8 changed files with 65 additions and 28 deletions

View File

@ -118,8 +118,17 @@ export async function buildGalleryList(options = {}) {
};
const galleryFiles = await globby(
galleryFilesPattern.map((pattern) => join(rootDirectory, pattern, "**/*")),
galleryFilesPattern.map((pattern) =>
// globby can only work with paths using '/' but node on windows uses '\'
// convert them right before passing to globby to ensure all joins work as expected
join(rootDirectory, pattern, "**/*").replaceAll("\\", "/"),
),
);
if (galleryFiles.length === 0) {
console.warn(
"Did not find any gallery files. Please check the configuration is correct",
);
}
const yamlFiles = galleryFiles.filter((path) =>
basename(path).match(galleryItemConfig),
);

View File

@ -9,10 +9,10 @@ import { fileURLToPath } from "node:url";
* @returns {number} exit code from the tsc command
*/
export default async function typescriptCompile(configPath) {
const tsPath = import.meta.resolve("typescript");
const binPath = fileURLToPath(join(tsPath, "../../bin/tsc"));
const tsPath = fileURLToPath(import.meta.resolve("typescript"));
const binPath = join(tsPath, "../../bin/tsc");
return new Promise((resolve, reject) => {
const ls = spawn(binPath, ["-p", configPath]);
const ls = spawn(process.execPath, [binPath, "-p", configPath]);
ls.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);

View File

@ -5,9 +5,9 @@ import {
RefObject,
useCallback,
useContext,
useDeferredValue,
useEffect,
useImperativeHandle,
useMemo,
useReducer,
useRef,
useState,
@ -29,7 +29,7 @@ import {
} from "./Gallery/GalleryItemStore.ts";
import Gallery from "./Gallery/Gallery.js";
import Bucket from "./Bucket.tsx";
import { Bucket, BucketPlaceholder } from "./Bucket.tsx";
import SandcastleEditor from "./SandcastleEditor.tsx";
import {
add,
@ -51,6 +51,7 @@ import { LeftPanel, SettingsContext } from "./SettingsContext.ts";
import { MetadataPopover } from "./MetadataPopover.tsx";
import { SharePopover } from "./SharePopover.tsx";
import { SandcastlePopover } from "./SandcastlePopover.tsx";
import { urlSpecifiesSandcastle } from "./Gallery/loadFromUrl.ts";
const defaultJsCode = `import * as Cesium from "cesium";
@ -199,7 +200,7 @@ function App() {
const consoleCollapsedHeight = 33;
const [consoleExpanded, setConsoleExpanded] = useState(false);
const isStartingWithCode = !!(window.location.search || window.location.hash);
const isStartingWithCode = useMemo(() => urlSpecifiesSandcastle(), []);
const startOnEditor =
isStartingWithCode || settings.defaultPanel === "editor";
const [leftPanel, setLeftPanel] = useState<LeftPanel>(
@ -385,7 +386,6 @@ function App() {
const [initialized, setInitialized] = useState(false);
const [isLoadPending, startLoadPending] = useTransition();
const deferredIsLoading = useDeferredValue(isLoadPending);
const { useLoadFromUrl } = galleryItemStore;
const loadFromUrl = useLoadFromUrl();
useEffect(() => {
@ -607,9 +607,16 @@ function App() {
dispatch({ type: "setHtml", html: value })
}
onRun={() => runSandcastle()}
js={codeState.code}
html={codeState.html}
js={
!initialized || isLoadPending ? "// Loading..." : codeState.code
}
html={
!initialized || isLoadPending
? "<!-- Loading... -->"
: codeState.html
}
setJs={(newCode) => dispatch({ type: "setCode", code: newCode })}
readOnly={!initialized}
/>
)}
<StoreContext value={galleryItemStore}>
@ -628,7 +635,9 @@ function App() {
setConsoleExpanded={setConsoleExpanded}
>
<Allotment.Pane minSize={200}>
{!deferredIsLoading && (
{!initialized || isLoadPending ? (
<BucketPlaceholder />
) : (
<Bucket
code={codeState.committedCode}
html={codeState.committedHtml}

View File

@ -19,5 +19,12 @@
border: none;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 1.5rem;
font-family: sans-serif;
color: #eee;
}
}

View File

@ -11,7 +11,7 @@ type SandcastleMessage =
| { type: "consoleError"; error: string; lineNumber?: number; url?: string }
| { type: "highlight"; highlight: number };
function Bucket({
export function Bucket({
code,
html,
runNumber,
@ -218,4 +218,10 @@ function Bucket({
);
}
export default Bucket;
export function BucketPlaceholder() {
return (
<div className="bucket-container">
<div className="fullFrame">Loading...</div>
</div>
);
}

View File

@ -37,6 +37,23 @@ const fromItem = async ({ getHtmlCode, getJsCode, title }: GalleryItem) => {
}
};
/**
* Check whether the current page's url indicates a specific sandcastle.
* This is required in case other search params are included in the url that
* don't point to a sandcastle like those needed for oauth
*/
export function urlSpecifiesSandcastle() {
console.log("check url", window.location);
const searchParams = new URLSearchParams(window.location.search);
return (
searchParams.has("id") ||
(searchParams.has("code") && !searchParams.has("state")) ||
window.location.hash.indexOf("#c") === 0 ||
searchParams.has("src") ||
searchParams.has("gist")
);
}
export function loadFromUrl(
items: GalleryItem[],
legacyIds: Record<string, string>,
@ -46,7 +63,7 @@ export function loadFromUrl(
const codeParam = searchParams.get("code");
if (codeParam) {
// This is a legacy support type url that was used by ion.
// Ideally we use the #c= param as that results in shorter urls
// Ideally we use the #c= param as that results in slightly shorter urls
// The code query parameter is a Base64 encoded JSON string with `code` and `html` properties.
const json = JSON.parse(window.atob(codeParam.replaceAll(" ", "+")));

View File

@ -64,6 +64,7 @@ function SandcastleEditor({
onHtmlChange,
onRun: onRunSandcastle,
setJs,
readOnly,
}: {
ref?: RefObject<SandcastleEditorRef | null>;
darkTheme: boolean;
@ -73,6 +74,7 @@ function SandcastleEditor({
onHtmlChange: OnChange;
onRun: () => void;
setJs: (newCode: string) => void;
readOnly: boolean;
}) {
const [activeTab, setActiveTab] = useState<"js" | "html">("js");
const internalEditorRef = useRef<monaco.editor.IStandaloneCodeEditor>(null);
@ -379,6 +381,7 @@ Sandcastle.addToolbarMenu(${variableName});`);
availableFonts[fontFamily]?.cssValue ?? "Droid Sans Mono",
fontSize: fontSize,
fontLigatures: fontLigatures,
readOnly: readOnly,
}}
path={activeTab === "js" ? "script.js" : "index.html"}
language={activeTab === "js" ? "javascript" : "html"}

View File

@ -10,15 +10,6 @@ import { buildGalleryList } from "../packages/sandcastle/scripts/buildGallery.js
const __dirname = dirname(fileURLToPath(import.meta.url));
const projectRoot = join(__dirname, "..");
// async function importSandcastleBuildFunctions() {
// // Import asynchronously, for now, because this script is not included or run in the release zip;
// const buildGalleryScriptPath = join(
// __dirname,
// "../packages/sandcastle/index.js",
// );
// return await import(pathToFileURL(buildGalleryScriptPath).href);
// }
/**
* Parses Sandcastle config file and returns its values.
* @returns {Promise<Record<string,any>>} A promise that resolves to the config values.
@ -52,10 +43,7 @@ export async function buildSandcastleApp({
outputToBuildDir,
includeDevelopment,
}) {
// const { join, dirname } = path;
const __dirname = dirname(fileURLToPath(import.meta.url));
// const { createSandcastleConfig, buildStatic } =
// await importSandcastleBuildFunctions();
const version = await getVersion();
let config;
if (outputToBuildDir) {
@ -168,8 +156,6 @@ export async function buildSandcastleGallery({
metadata,
} = gallery ?? {};
// const { buildGalleryList } = await importSandcastleBuildFunctions();
await buildGalleryList({
rootDirectory,
publicDirectory: outputDir,