diff --git a/src/livecodes/config/validate-config.ts b/src/livecodes/config/validate-config.ts index 11dcb1395..73a4f2754 100644 --- a/src/livecodes/config/validate-config.ts +++ b/src/livecodes/config/validate-config.ts @@ -35,7 +35,11 @@ export const validateConfig = (config: Partial): Partial => { const isEditor = (x: any) => is(x, 'object') && - (is(x.language, 'string') || is(x.content, 'string') || is(x.contentUrl, 'string')); + (is(x.language, 'string') || + is(x.content, 'string') || + is(x.contentUrl, 'string') || + is(x.hiddenContent, 'string') || + is(x.hiddenContentUrl, 'string')); const validateEditorProps = (x: Editor, editorId: EditorId): Editor => ({ language: @@ -44,14 +48,20 @@ export const validateConfig = (config: Partial): Partial => { : defaultConfig[editorId].language, ...(is(x.content, 'string') ? { content: x.content } : {}), ...(is(x.contentUrl, 'string') ? { contentUrl: x.contentUrl } : {}), + ...(is(x.hiddenContent, 'string') ? { hiddenContent: x.hiddenContent } : {}), + ...(is(x.hiddenContentUrl, 'string') ? { hiddenContentUrl: x.hiddenContentUrl } : {}), ...(is(x.selector, 'string') ? { selector: x.selector } : {}), + ...(is(x.position, 'object') ? { position: x.position } : {}), }); const validateTestsProps = (x: Partial): Partial => ({ ...(x && is(x.language, 'string') ? { language: x.language } : {}), ...(x && is(x.content, 'string') ? { content: x.content } : {}), ...(x && is(x.contentUrl, 'string') ? { contentUrl: x.contentUrl } : {}), + ...(x && is(x.hiddenContent, 'string') ? { hiddenContent: x.hiddenContent } : {}), + ...(x && is(x.hiddenContentUrl, 'string') ? { hiddenContentUrl: x.hiddenContentUrl } : {}), ...(x && is(x.selector, 'string') ? { selector: x.selector } : {}), + ...(x && is(x.position, 'object') ? { position: x.position } : {}), }); const validateToolsProps = (x: Partial): Config['tools'] => ({ diff --git a/src/livecodes/core.ts b/src/livecodes/core.ts index 1c55ee3e0..1719393c3 100644 --- a/src/livecodes/core.ts +++ b/src/livecodes/core.ts @@ -55,6 +55,7 @@ import type { APICommands, CompileInfo, SDKEvent, + Editor, } from './models'; import type { GitHubFile } from './services/github'; import type { @@ -665,13 +666,17 @@ const configureEditorTools = (language: Language) => { return true; }; +const addPhpToken = (code: string) => (code.trim().startsWith(' + code.trim().startsWith(' { - const addToken = (code: string) => (code.trim().startsWith(' | undefined) => { + if (!editor?.hiddenContent) { + return editor?.content || ''; + } + const editorContent = editor.language?.startsWith('php') + ? removePhpToken(editor.content || '') + : editor.content || ''; + const hiddenContent = editor.language?.startsWith('php') + ? removePhpToken(editor.hiddenContent || '') + : editor.hiddenContent || ''; + const token = editor.language?.startsWith('php') ? ' name === p.name && p.needsHTML), ) && (config.processors.join(',') !== getCache().processors.join(',') || - markupContent !== getCache().markup.content || - scriptContent !== getCache().script.content); /* e.g. jsx/sfc */ + markupContent !== getContent(getCache().markup) || + scriptContent !== getContent(getCache().script)); /* e.g. jsx/sfc */ const testsNotChanged = config.tests?.language === getCache().tests?.language && @@ -3892,8 +3915,11 @@ const importExternalContent = async (options: { const { config = defaultConfig, configUrl, template, url } = options; const editorIds: EditorId[] = ['markup', 'style', 'script']; const hasContentUrls = (conf: Partial) => - editorIds.filter((editorId) => conf[editorId]?.contentUrl && !conf[editorId]?.content).length > - 0; + editorIds.filter( + (editorId) => + (conf[editorId]?.contentUrl && !conf[editorId]?.content) || + (conf[editorId]?.hiddenContentUrl && !conf[editorId]?.hiddenContent), + ).length > 0; if (!configUrl && !template && !url && !hasContentUrls(config)) return false; @@ -3943,18 +3969,22 @@ const importExternalContent = async (options: { if (hasContentUrls(config)) { // load content from config contentUrl const editorsContent = await Promise.all( - editorIds.map((editorId) => { + editorIds.map(async (editorId) => { const contentUrl = config[editorId].contentUrl; - if (contentUrl && getValidUrl(contentUrl) && !config[editorId].content) { - return fetch(contentUrl) - .then((res) => res.text()) - .then((content) => ({ - ...config[editorId], - content, - })); - } else { - return Promise.resolve(config[editorId]); - } + const hiddenContentUrl = config[editorId].hiddenContentUrl; + const [content, hiddenContent] = await Promise.all([ + contentUrl && getValidUrl(contentUrl) && !config[editorId].content + ? fetch(contentUrl).then((res) => res.text()) + : Promise.resolve(''), + hiddenContentUrl && getValidUrl(hiddenContentUrl) && !config[editorId].hiddenContent + ? fetch(hiddenContentUrl).then((res) => res.text()) + : Promise.resolve(''), + ]); + return { + ...config[editorId], + ...(content ? { content } : {}), + ...(hiddenContent ? { hiddenContent } : {}), + }; }), ); contentUrlConfig = { diff --git a/src/sdk/models.ts b/src/sdk/models.ts index 8f2be3c4d..25c27bee7 100644 --- a/src/sdk/models.ts +++ b/src/sdk/models.ts @@ -339,6 +339,8 @@ export interface Editor { language: Language; content?: string; contentUrl?: string; + hiddenContent?: string; + hiddenContentUrl?: string; selector?: string; position?: EditorPosition; }