Skip to content
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
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,15 @@
"code",
"plugin"
]
},
{
"login": "pablopunk",
"name": "Pablo Varela",
"avatar_url": "https://avatars0.githubusercontent.com/u/4324982?v=4",
"profile": "https://pablo.pink",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ Thanks goes to these wonderful people
<tr>
<td align="center"><a href="https://github.com/NinoMaj"><img src="https://avatars0.githubusercontent.com/u/20380632?v=4" width="100px;" alt="Nino"/><br /><sub><b>Nino</b></sub></a><br /><a href="https://github.com/codesandbox/codesandbox-client/commits?author=NinoMaj" title="Documentation">📖</a></td>
<td align="center"><a href="https://saurabhdaware.in/"><img src="https://avatars1.githubusercontent.com/u/30949385?v=4" width="100px;" alt="Saurabh Daware"/><br /><sub><b>Saurabh Daware</b></sub></a><br /><a href="https://github.com/codesandbox/codesandbox-client/commits?author=saurabhdaware" title="Code">💻</a> <a href="#plugin-saurabhdaware" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="https://pablo.pink"><img src="https://avatars0.githubusercontent.com/u/4324982?v=4" width="100px;" alt="Pablo P Varela"/><br /><sub><b>Pablo P Varela</b></sub></a><br /><a href="https://github.com/codesandbox/codesandbox-client/commits?author=pablopunk" title="Code">💻</a></td>
</tr>
</table>

Expand Down
12 changes: 11 additions & 1 deletion packages/app/src/app/overmind/effects/zip/create-zip/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Directory, Module, Sandbox } from '@codesandbox/common/lib/types';
import { saveAs } from 'file-saver';
import ignore from 'ignore';
import JSZip from 'jszip';
import { injectExternalResources } from 'app/utils/inject-resources-for-export';

export const BLOB_ID = 'blob-url://';

Expand Down Expand Up @@ -215,7 +216,16 @@ export async function createZip(
ignorer.add(gitIgnore ? gitIgnore.code : '');
}

const filteredModules = modules.filter(module => {
let modifiedModules = modules;

if (sandbox.externalResources?.length > 0) {
modifiedModules = injectExternalResources(
modules,
sandbox.externalResources
);
}

const filteredModules = modifiedModules.filter(module => {
// Relative path
const path = getModulePath(modules, directories, module.id).substring(1);
return !ignorer.ignores(path);
Expand Down
44 changes: 44 additions & 0 deletions packages/app/src/app/utils/inject-resources-for-export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Module } from '@codesandbox/common/lib/types';
import {
resourceIsCss,
createExternalCSSLink,
createExternalJSLink,
} from 'sandbox/external-resources';

function isFileHTML(path: string) {
return /\.html$/g.test(path);
}

function addElementToHTMLHead(code: string, resource: string) {
const element: HTMLLinkElement | HTMLScriptElement = resourceIsCss(resource)
? createExternalCSSLink(resource)
: createExternalJSLink(resource);

const newCode = code.replace(/<\/head>/g, `\t${element.outerHTML}\n</head>`);

return newCode;
}

// Returns the modules with the externalResources injected.
// Useful for static exports.
export function injectExternalResources(
modules: Module[],
externalResources: string[]
): Module[] {
const modifiedModules = modules.map(mod => {
const modifiedModule = { ...mod };

if (mod.type === 'file' && isFileHTML(mod.path)) {
externalResources.forEach(resource => {
modifiedModule.code = addElementToHTMLHead(
modifiedModule.code,
resource
);
});
}

return modifiedModule;
});

return modifiedModules;
}
35 changes: 26 additions & 9 deletions packages/app/src/sandbox/external-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function getExternalResourcesConcatenation(resources: Array<string>) {
}
/* eslint-disable no-cond-assign */
function clearExternalResources() {
let el = null;
let el: HTMLElement | null = null;
// eslint-disable-next-line no-cond-assign
while ((el = document.getElementById('external-css'))) {
el.remove();
Expand All @@ -16,36 +16,53 @@ function clearExternalResources() {
}
/* eslint-enable */

function addCSS(resource: string) {
const head = document.getElementsByTagName('head')[0];
export function createExternalCSSLink(resource: string): HTMLLinkElement {
const link = document.createElement('link');

link.id = 'external-css';
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = resource;
link.media = 'all';

return link;
}

function addCSS(resource: string) {
const head = document.getElementsByTagName('head')[0];
const link = createExternalCSSLink(resource);

head.appendChild(link);

return link;
}

function addJS(resource: string) {
export function createExternalJSLink(resource): HTMLScriptElement {
const script = document.createElement('script');

script.setAttribute('src', resource);
script.async = false;
script.setAttribute('id', 'external-js');

return script;
}

function addJS(resource: string) {
const script = createExternalJSLink(resource);

document.head.appendChild(script);

return script;
}

function addResource(resource: string) {
export function resourceIsCss(resource: string): boolean {
const match = resource.match(/\.([^.]*)$/);

const el =
(match && match[1] === 'css') || resource.includes('fonts.googleapis')
? addCSS(resource)
: addJS(resource);
return (match && match[1] === 'css') || resource.includes('fonts.googleapis');
}

function addResource(resource: string) {
const el = resourceIsCss(resource) ? addCSS(resource) : addJS(resource);

return new Promise(r => {
el.onload = r;
Expand Down