Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/zyf722/livecodes into i1…
Browse files Browse the repository at this point in the history
…8next-integration-draft
  • Loading branch information
zyf722 committed Oct 28, 2024
2 parents 9698012 + f97ff44 commit bb7f971
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 61 deletions.
64 changes: 64 additions & 0 deletions src/livecodes/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,69 @@ const getVersion = (log = true) => {
};
};

const showConsoleMessage = () => {
if (isEmbed) return;
const docsBaseUrl = predefinedValues.DOCS_BASE_URL || 'docs';
const docsUrl = docsBaseUrl?.startsWith('http')
? docsBaseUrl
: new URL(docsBaseUrl, location.href).href;

const items = [
{
content: ' ',
style:
'padding-left: 2.5em; line-height: 4em; background-size: 2.5em; background-repeat: no-repeat; background-position: left center; background-image: url("data:image/svg+xml;charset=UTF-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzciIGhlaWdodD0iNDg4IiAgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHN0eWxlPjwhW0NEQVRBWy5Ce3N0cm9rZTpub25lfS5De2ZpbGw6dXJsKCNDKX0uRHtmaWxsOiM5NmJmM2R9LkV7ZmlsbC1ydWxlOm5vbnplcm99XV0+PC9zdHlsZT48ZGVmcz48ZmlsdGVyIGlkPSJBIiB4PSItMS44MTgyJSIgeT0iLTIuNzIyOSUiIHdpZHRoPSIxMDQuMDU1OSUiIGhlaWdodD0iMTA2LjA3NDElIj48ZmVHYXVzc2lhbkJsdXIgaW49IlNvdXJjZUFscGhhIiBzdGREZXZpYXRpb249IjUiLz48ZmVPZmZzZXQgZHg9IjMiIGR5PSIzIiByZXN1bHQ9IkIiLz48ZmVGbG9vZCBmbG9vZC1jb2xvcj0iIzAwMCIgZmxvb2Qtb3BhY2l0eT0iLjUiLz48ZmVDb21wb3NpdGUgaW4yPSJCIiBvcGVyYXRvcj0iaW4iIHJlc3VsdD0iQyIvPjxmZU1lcmdlPjxmZU1lcmdlTm9kZSBpbj0iQyIvPjxmZU1lcmdlTm9kZSBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmVNZXJnZT48L2ZpbHRlcj48ZmlsdGVyIGlkPSJCIiB4PSItNC40MDY4JSIgeT0iLTMuNjExMSUiIHdpZHRoPSIxMDkuODMwNSUiIGhlaWdodD0iMTA4LjA1NTYlIj48ZmVHYXVzc2lhbkJsdXIgaW49IlNvdXJjZUFscGhhIiBzdGREZXZpYXRpb249IjUiLz48ZmVPZmZzZXQgZHg9IjMiIGR5PSIzIiByZXN1bHQ9IkIiLz48ZmVGbG9vZCBmbG9vZC1jb2xvcj0iIzAwMCIgZmxvb2Qtb3BhY2l0eT0iLjUiLz48ZmVDb21wb3NpdGUgaW4yPSJCIiBvcGVyYXRvcj0iaW4iIHJlc3VsdD0iQyIvPjxmZU1lcmdlPjxmZU1lcmdlTm9kZSBpbj0iQyIvPjxmZU1lcmdlTm9kZSBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmVNZXJnZT48L2ZpbHRlcj48bGluZWFyR3JhZGllbnQgaWQ9IkMiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNkN2Q3ZDciLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2MjYyNjIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48ZyBmaWx0ZXI9InVybCgjQSkiIGZpbGw9IiNjMWMxYzEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDkuNSA0LjUpIiBjbGFzcz0iQiBFIj48cGF0aCBkPSJNMTYuNzUyNSAyODYuNzI5OEM2LjcwNjYgMjc1Ljc0NTUgMCAyNTMuODA5NyAwIDIzNC41OTA5YzAtMTkuMjA2MSA1LjAyNjYtMzcuMDMyIDE3LjU4OTEtNDYuNjMzNmgtLjgzNTdMMjE0LjQyOTIgMHYxMjcuNTk2NGMtMjEuNzc4NCAyMC41NzYyLTUxLjA5MzkgNDMuOTA1Ny0xMjQuODAyOCAxMDguMzg5MWwuODM1NyAxLjM1NTJjMzkuMzY3MyAyOC44MjIgODQuNTk4OCA3Mi43MTYzIDEyMy45NjYyIDExMS4xMjk3djEyOC45NjZ6Ii8+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTAwLjU3MTYgLjAwMTcpIj48cGF0aCBkPSJNMTk3LjY3NjEgMTkwLjY5NTZjMTAuMDM4NSAxMC45ODUgMTYuNzUyMyAzMi45MzE3IDE2Ljc1MjMgNTIuMTM5NnMtNS4wMjY4IDM3LjAzMDgtMTcuNTk2MiA0Ni42MzM2aC44NDQzTDAgNDc3LjQyNjZWMzQ5LjgyOTdjMjEuNzc5My0yMC41NjQ4IDUxLjA5NC00My44OTM3IDEyNC44MDM0LTEwOC4zNzc3bC0uODM1Ny0xLjM1NTNDODQuNjA3IDIxMS4yNzQ3IDM5LjM2OTIgMTY3LjM3OTkuMDAwOSAxMjguOTY3NlYweiIvPjwvZz48L2c+PGcgZmlsdGVyPSJ1cmwoI0IpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMTkuNSA1OS41KSIgY2xhc3M9IkIiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0Ny4yMjkgOTIuNTk1MSkiPjxwYXRoIGQ9Ik0wIDI2MS45MjM4bDE0My4xNjk4LTg3LjQ1MzRWMEwwIDg3LjIxMDl2MTc0LjcxMjl6Ii8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQuMzMwMiA5Mi43NDA1KSI+PHBhdGggZD0iTTAgMTc0LjI3NjRsMTQyLjk4OTQgODcuMzA4MVY4Ny4xMTQyTDAgMHYxNzQuMjc2NHoiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNS4yMzI1IDYuMDE0NykiPjxwYXRoIGQ9Ik0yODQuMTc0MyA4Ni41ODA1TDE0Mi4wODcyIDAgMCA4Ni41ODA1bDE0Mi4wODcyIDg2LjcyNTcgMTQyLjA4NzEtODYuNzI1N3oiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ3LjMxOTYgOTIuNTk1MSkiPjxwYXRoIGQ9Ik0wIDgxLjU4NDVMMTMzLjgzMjcuMDk2NyAxMzMuNjk3NCAwIDAgODEuNTg0NXoiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMuNDg3IDkyLjU5NTEpIj48cGF0aCBkPSJNLjEzNTMgMEwwIC4wOTY3bDEzMy44MzI3IDgxLjQ4NzhMLjEzNTMgMHoiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ3LjMxOTYgMTc0LjE3OTIpIj48cGF0aCBkPSJNMCAweiIvPjwvZz48cGF0aCBkPSJNMjkwLjEyODcgODcuMDE3TDE0Ny4zMTk2IDAgNC41MTA2IDg3LjAxNyAwIDg5Ljg3ODl2MTgwLjA0ODJMMTQ3LjUgMzYwbDQuNTEwNi0yLjc2NDhMMjk1IDI2OS45MjcxVjg5LjgzMDN6bS00LjUxMSAxNzcuMjgzN2wtMTMzLjc4NzUgODEuNzc4NlYxODIuNjE5NGwxMzMuOTY3OS04MS42MzMxem0tMTQyLjgwOSA4MS43Nzg2TDguODQwNyAyNjQuMjUyMVYxMDAuOTg2M2wxMzMuOTY4IDgxLjYzMzF6TTEzLjYyMjMgOTIuNjkxOWwxMzMuNjk3My04MS41MzYgMTMzLjY5NzQgODEuNTM2LTEzMy42OTc0IDgxLjQ4NzNMMTMuNDg3IDkyLjY5MTl6IiBmaWxsPSIjNDQ0Ii8+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQ3LjkwNTggMTMzLjQ4NDQpIiBjbGFzcz0iQyI+PHBhdGggZD0iTTAgMTQwLjU2Nmw3Ni45MDczLTQ2LjkwMzlWMEwwIDQ2Ljg1NTN2OTMuNzEwN3oiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjkuODI1NyAxMzMuNDg0NCkiIGNsYXNzPSJDIj48cGF0aCBkPSJNMCA5My42NjIxbDc2LjkwNzMgNDYuOTAzOVY0Ni44NTUzTDAgMHY5My42NjIxeiIvPjwvZz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MC42MzczIDg1LjUxMykiIGNsYXNzPSJDIj48cGF0aCBkPSJNMTUzLjM2MzggNDYuNzFMNzYuNjgxOSAwIDAgNDYuNzFsNzYuNjgxOSA0Ni44NTU0TDE1My4zNjM4IDQ2LjcxeiIvPjwvZz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNDcuMzE5NiAxMzIuMjIzKSIgY2xhc3M9IkQiPjxwYXRoIGQ9Ik0wIDQyLjEwMkw2OC45Njg1LjA5NjggNjguODc4NyAwIDAgNDIuMDUzNHYuMDQ4NnoiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzguMzUwNyAxMzIuMjIzKSIgY2xhc3M9IkQiPjxwYXRoIGQ9Ik0uMDkwMiAwTDAgLjA5NjggNjguOTY4NSA0Mi4xMDJ2LS4wNDg2TC4wOTAyIDB6Ii8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0Ny4zMTk2IDE3NC4yNzY0KSIgY2xhc3M9IkQiPjxwYXRoIGQ9Ik0wIDB6Ii8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY0Ljc3MzYgNzkuMTU5KSI+PHBhdGggZD0iTTE2MC41ODExIDQ3LjQ4NThMODIuNTQ1NiAwIDQuNTEwNiA0Ny40ODU4IDAgNTAuMjk5MnYxMDAuOTM3N2w4Mi41NDU2IDUwLjQ0NDYgNC41MTEtMi43NjQ4IDc4LjEyNTMtNDcuNjc5OFY1MC4yOTkyem0tNC41MTA5IDk4LjA3NjJsLTY5LjAxMzYgNDIuMTk4N3YtODQuMjAzNWw2OS4xMDQyLTQyLjEwMnptLTc4LjAzNTEgNDIuMTk4N0w4LjkzMDkgMTQ1LjU2MlY2MS40NTUybDY5LjEwNDIgNDIuMTAyek0xMy42Njc0IDUzLjA2NGw2OC44NzgyLTQxLjkwOCA2OC44Nzg3IDQxLjk1NjYtNjguODc4NyA0Mi4wMDQ4LTY4Ljk2ODQtNDEuOTU2NnoiLz48L2c+PC9nPjwvc3ZnPg==");',
},
{ content: 'LiveCodes', style: 'font-weight: bold; font-size: 1.2em;' },
{ content: ' - ', style: 'font-size: 1.2em;' },
{
content:
window.deps.translateString('generic.tagline', 'A Code Playground That Just Works!') + '\n',
style: 'font-style: italic; font-size: 1.2em;',
},
{
content: window.deps.translateString('about.version.app', `App version: {{APP_VERSION}}`, {
APP_VERSION: predefinedValues.APP_VERSION,
}),
style: 'padding: 0.2em 0.4em; border-radius: 0.5em; background: hsl(0,0%,40%); color: white;',
},
{ content: ' ', style: '' },
{
content: window.deps.translateString('about.version.sdk', `SDK version: {{SDK_VERSION}}`, {
SDK_VERSION: predefinedValues.SDK_VERSION,
}),
style: 'padding: 0.2em 0.4em; border-radius: 0.5em; background: hsl(0,0%,40%); color: white;',
},
{ content: ' ', style: '' },
{
content: window.deps.translateString('about.version.commit', `Git commit: {{COMMIT_SHA}}`, {
COMMIT_SHA: predefinedValues.COMMIT_SHA,
}),
style: 'padding: 0.2em 0.4em; border-radius: 0.5em; background: hsl(0,0%,40%); color: white;',
},
{ content: '\n\n', style: '' },
{
content: window.deps.translateString(
'app.consoleMessage.learnMore',
'Learn more! {{docsUrl}} 🚀',
{ docsUrl },
),
style: 'padding: 0.2em 0.4em; font-size: 1.1em;',
},
];

const message = items.reduce(
(acc, item) => {
acc[0] += `%c${item.content}`;
acc.push(item.style);
return acc;
},
[''],
);

parent.postMessage({ args: 'console-message', payload: message }, location.origin);
};

const resizeEditors = () => {
Object.values(editors).forEach((editor: CodeEditor) => {
setTimeout(() => {
Expand Down Expand Up @@ -4253,6 +4316,7 @@ const extraHandlers = async () => {
handleBroadcastStatus();
handleDropFiles();
handleUnload();
showConsoleMessage();
};

const configureEmbed = (config: Config, eventsManager: ReturnType<typeof createEventsManager>) => {
Expand Down
54 changes: 54 additions & 0 deletions src/livecodes/i18n/locale-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,66 @@ export const pathLoader = (baseUrl: string) => (lngs: string[], nss: string[]) =
if (lng === 'ar' && ns === 'translation') {
return baseUrl + '{{hash:i18n-ar-translation.json}}';
}
if (lng === 'de' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-de-language-info.json}}';
}
if (lng === 'de' && ns === 'translation') {
return baseUrl + '{{hash:i18n-de-translation.json}}';
}
if (lng === 'en' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-en-language-info.json}}';
}
if (lng === 'en' && ns === 'translation') {
return baseUrl + '{{hash:i18n-en-translation.json}}';
}
if (lng === 'es' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-es-language-info.json}}';
}
if (lng === 'es' && ns === 'translation') {
return baseUrl + '{{hash:i18n-es-translation.json}}';
}
if (lng === 'fr' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-fr-language-info.json}}';
}
if (lng === 'fr' && ns === 'translation') {
return baseUrl + '{{hash:i18n-fr-translation.json}}';
}
if (lng === 'hi' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-hi-language-info.json}}';
}
if (lng === 'hi' && ns === 'translation') {
return baseUrl + '{{hash:i18n-hi-translation.json}}';
}
if (lng === 'it' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-it-language-info.json}}';
}
if (lng === 'it' && ns === 'translation') {
return baseUrl + '{{hash:i18n-it-translation.json}}';
}
if (lng === 'ja' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-ja-language-info.json}}';
}
if (lng === 'ja' && ns === 'translation') {
return baseUrl + '{{hash:i18n-ja-translation.json}}';
}
if (lng === 'pt' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-pt-language-info.json}}';
}
if (lng === 'pt' && ns === 'translation') {
return baseUrl + '{{hash:i18n-pt-translation.json}}';
}
if (lng === 'ru' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-ru-language-info.json}}';
}
if (lng === 'ru' && ns === 'translation') {
return baseUrl + '{{hash:i18n-ru-translation.json}}';
}
if (lng === 'ur' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-ur-language-info.json}}';
}
if (lng === 'ur' && ns === 'translation') {
return baseUrl + '{{hash:i18n-ur-translation.json}}';
}
if (lng === 'zh-CN' && ns === 'language-info') {
return baseUrl + '{{hash:i18n-zh-CN-language-info.json}}';
}
Expand Down
8 changes: 8 additions & 0 deletions src/livecodes/i18n/locales/en/translation.lokalise.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
"notes": "",
"translation": "SDK Permanent URL"
},
"app.consoleMessage.learnMore": {
"notes": "",
"translation": "Learn more! {{docsUrl}} 🚀"
},
"app.copy.hint": {
"notes": "",
"translation": "Copy (Ctrl/Cmd + A, Ctrl/Cmd + C)"
Expand Down Expand Up @@ -1076,6 +1080,10 @@
"notes": "",
"translation": "Required"
},
"generic.tagline": {
"notes": "",
"translation": "A Code Playground That Just Works!"
},
"import.bulk.desc": {
"notes": "### <tag-1> ###\n<a href=\"#\" id=\"link-to-saved-projects\" />\n\n",
"translation": "Bulk import multiple projects to your saved projects. Projects can be exported from the <tag-1>Saved Projects</tag-1> screen."
Expand Down
4 changes: 4 additions & 0 deletions src/livecodes/i18n/locales/en/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const translation = {
},
},
app: {
consoleMessage: {
learnMore: 'Learn more! {{docsUrl}} 🚀',
},
copy: {
hint: 'Copy (Ctrl/Cmd + A, Ctrl/Cmd + C)',
},
Expand Down Expand Up @@ -454,6 +457,7 @@ const translation = {
more: 'More...',
optional: 'Optional',
required: 'Required',
tagline: 'A Code Playground That Just Works!',
},
import: {
bulk: {
Expand Down
126 changes: 65 additions & 61 deletions src/livecodes/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,74 @@ export const livecodes = (container: string, config: Partial<Config> = {}): Prom
registerSDKEvent(customEvents.destroy);
}

let api: API | null = null;

addEventListener(
'message',
async (
e: MessageEventInit<{ method: keyof API; id: string; args: any; payload?: any }>,
) => {
if (isEmbed) {
if (e.source !== parent || api == null) return;
const { method, id, args } = e.data ?? {};
if (!method || !id) return;
const methodArguments = Array.isArray(args) ? args : [args];
let payload: any;
try {
payload = await (api[method] as any)(...methodArguments);
} catch (error: any) {
payload = { error: error.message || error };
}
if (typeof payload === 'object') {
Object.keys(payload).forEach((key) => {
if (typeof payload[key] === 'function') {
delete payload[key];
}
});
}
parent.postMessage(
{
type: customEvents.apiResponse,
method,
id,
payload,
},
anyOrigin,
);
} else {
if (e.source !== iframe.contentWindow) return;
if (e.data?.args === 'home') {
location.href = location.origin + location.pathname;
} else if (e.data?.args === 'console-message') {
// eslint-disable-next-line no-console
console.info(...(e.data.payload ?? []));
} else if (e.data?.args === 'i18n') {
// flatten i18n object `splash` and save to localStorage
const i18nSplashData = e.data.payload.data as { [k: string]: string };
for (const [key, value] of Object.entries(i18nSplashData)) {
localStorage.setItem(`i18n_splash.${key}`, value);
}

// Set document language
const lang = e.data.payload.lang as string;
document.documentElement.lang = lang;

// Reload the page to apply the new language
const reload = e.data.payload.reload as boolean;
if (reload) {
const url = new URL(location.href);
url.searchParams.delete('appLanguage');
location.href = url.href;
}
}
}
},
);

iframe.addEventListener('load', async () => {
const app = (iframe.contentWindow as any)?.app;
if (typeof app === 'function') {
const api: API = await app(config, baseUrl);
api = (await app(config, baseUrl)) as API;
if (!isHeadless) {
iframe.style.display = 'block';
}
Expand All @@ -146,66 +210,6 @@ export const livecodes = (container: string, config: Partial<Config> = {}): Prom
detail: api,
}),
);

addEventListener(
'message',
async (
e: MessageEventInit<{ method: keyof API; id: string; args: any; payload?: any }>,
) => {
if (isEmbed) {
if (e.source !== parent) return;
const { method, id, args } = e.data ?? {};
if (!method || !id) return;
const methodArguments = Array.isArray(args) ? args : [args];
let payload: any;
try {
payload = await (api[method] as any)(...methodArguments);
} catch (error: any) {
payload = { error: error.message || error };
}
if (typeof payload === 'object') {
Object.keys(payload).forEach((key) => {
if (typeof payload[key] === 'function') {
delete payload[key];
}
});
}
parent.postMessage(
{
type: customEvents.apiResponse,
method,
id,
payload,
},
anyOrigin,
);
} else {
if (e.source !== iframe.contentWindow) return;
if (e.data?.args === 'home') {
location.href = location.origin + location.pathname;
} else if (e.data?.args === 'i18n') {
// flatten i18n object `splash` and save to localStorage
const i18nSplashData = e.data.payload.data as { [k: string]: string };
for (const [key, value] of Object.entries(i18nSplashData)) {
localStorage.setItem(`i18n_splash.${key}`, value);
}

// Set document language
const lang = e.data.payload.lang as string;
document.documentElement.lang = lang;

// Reload the page to apply the new language
const reload = e.data.payload.reload as boolean;
if (reload) {
const url = new URL(location.href);
url.searchParams.delete('appLanguage');
location.href = url.href;
}
}
}
},
);

resolve(api);
}
});
Expand Down

0 comments on commit bb7f971

Please sign in to comment.