p5.js-web-editor/server/utils/previewGeneration.js
Cassie Tarakajian 04922522cc cool to share some of this code between client and server
Squashed commit of the following:

commit fb5e82cea930b011792983c7d1cc9f6ecacc7dd4
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Wed Nov 16 12:28:10 2016 -0500

    add server side rendering, untested

commit 5c60fb30c46ea49a8d9a0ecb56f39ec778464a8b
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Tue Nov 15 18:26:06 2016 -0500

    add redux-form bandage post react update, should probably update to redux-form 6 at some point

commit 057b5871e7137179abc93f7821a9690f0ea52c92
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Tue Nov 15 16:30:09 2016 -0500

    remove passing jsFiles and cssFiles to PreviewFrame, fix rendering bug

commit 88c56fd36d3a8d88902c79642171988ce37825f2
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Tue Nov 15 16:21:59 2016 -0500

    code cleanup, untested

commit 82e5dcf8bca461892f1daf06d38f1eaebe72983f
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Tue Nov 15 15:53:50 2016 -0500

    update react and react router, fix a few bugs in rendering code, add ability to parse inline js and css

commit e02f4b67803ea45328eff4e53659222f3149964c
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Tue Nov 15 14:43:38 2016 -0500

    add almost full code to create preview html correctly, untested

commit 12f61b2a1aed4607fab24d01572b647ca6210262
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Wed Nov 2 17:09:26 2016 -0400

    refactor some of the preview html generation code

commit 111825846703d5c8959cb18795a3aadb7ebe505c
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Wed Nov 2 11:06:36 2016 -0400

    add comments as plan of action

commit 1cc2cf5203674732b4057382f1937de38b687078
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Thu Oct 27 19:34:55 2016 -0400

    add href parsing

commit e67189298cda9b70645f454ecd541a363980f0e4
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Thu Oct 27 10:48:36 2016 -0400

    continue parsing html

commit 1458fb940a15a3dc5d74890211a3073e920b84b8
Author: Cassie Tarakajian <ctarakajian@gmail.com>
Date:   Wed Oct 26 17:40:31 2016 -0400

    start to add html parsing
2016-11-16 13:12:36 -05:00

102 lines
4.4 KiB
JavaScript

import { resolvePathToFile } from '../utils/filePath';
const MEDIA_FILE_REGEX = /^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt|csv|svg|obj|mp4|ogg|webm|mov)('|")$/i;
const MEDIA_FILE_REGEX_NO_QUOTES = /^(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt|csv|svg|obj|mp4|ogg|webm|mov)$/i;
const STRING_REGEX = /(['"])((\\\1|.)*?)\1/gm;
const TEXT_FILE_REGEX = /(.+\.json$|.+\.txt$|.+\.csv$)/i;
const EXTERNAL_LINK_REGEX = /^(http:\/\/|https:\/\/)/;
const NOT_EXTERNAL_LINK_REGEX = /^(?!(http:\/\/|https:\/\/))/;
function resolveLinksInString(content, files, projectId) {
let newContent = content;
let fileStrings = content.match(STRING_REGEX);
const fileStringRegex = /^('|")(?!(http:\/\/|https:\/\/)).*('|")$/i;
fileStrings = fileStrings || [];
fileStrings.forEach(fileString => {
//if string does not begin with http or https
if (fileString.match(fileStringRegex)) {
const filePath = fileString.substr(1, fileString.length - 2);
const resolvedFile = resolvePathToFile(filePath, files);
if (resolvedFile) {
if (resolvedFile.url) {
newContent = newContent.replace(filePath,resolvedFile.url);
} else if (resolvedFile.name.match(/(.+\.json$|.+\.txt$|.+\.csv$)/i)) {
let resolvedFilePath = filePath;
if (resolvedFilePath.startsWith('.')) {
resolvedFilePath = resolvedFilePath.substr(1);
}
while (resolvedFilePath.startsWith('/')) {
resolvedFilePath = resolvedFilePath.substr(1);
}
newContent = newContent.replace(filePath, `/api/projects/${projectId}/${resolvedFilePath}`);
}
}
}
});
return newContent;
}
export function injectMediaUrls(filesToInject, allFiles, projectId) {
filesToInject.forEach((file, index) => {
file.content = resolveLinksInString(file.content, allFiles, projectId);
});
}
export function resolvePathsForElementsWithAttribute(attr, sketchDoc, files) {
const elements = sketchDoc.querySelectorAll(`[${attr}]`);
const elementsArray = Array.prototype.slice.call(elements);
elementsArray.forEach(element => {
if (element.getAttribute(attr).match(MEDIA_FILE_REGEX_NO_QUOTES)) {
const resolvedFile = resolvePathToFile(element.getAttribute(attr), files);
if (resolvedFile) {
element.setAttribute(attr, resolvedFile.url);
}
}
});
}
export function resolveScripts(sketchDoc, files, projectId) {
const scriptsInHTML = sketchDoc.getElementsByTagName('script');
const scriptsInHTMLArray = Array.prototype.slice.call(scriptsInHTML);
scriptsInHTMLArray.forEach(script => {
if (script.getAttribute('src') && script.getAttribute('src').match(NOT_EXTERNAL_LINK_REGEX) !== null) {
const resolvedFile = resolvePathToFile(script.getAttribute('src'), files);
if (resolvedFile) {
if (resolvedFile.url) {
script.setAttribute('src', resolvedFile.url);
} else {
script.removeAttribute('src');
script.innerHTML = resolvedFile.content;
}
}
} else if (!(script.getAttribute('src') && script.getAttribute('src').match(EXTERNAL_LINK_REGEX) !== null)) {
script.innerHTML = resolveLinksInString(script.innerHTML, files, projectId);
}
});
}
export function resolveStyles(sketchDoc, files, projectId) {
const inlineCSSInHTML = sketchDoc.getElementsByTagName('style');
const inlineCSSInHTMLArray = Array.prototype.slice.call(inlineCSSInHTML);
inlineCSSInHTMLArray.forEach(style => {
style.innerHTML = resolveLinksInString(style.innerHTML, files, projectId);
});
const cssLinksInHTML = sketchDoc.querySelectorAll('link[rel="stylesheet"]');
const cssLinksInHTMLArray = Array.prototype.slice.call(cssLinksInHTML);
cssLinksInHTMLArray.forEach(css => {
if (css.getAttribute('href') && css.getAttribute('href').match(NOT_EXTERNAL_LINK_REGEX) !== null) {
const resolvedFile = resolvePathToFile(css.getAttribute('href'), files);
if (resolvedFile) {
if (resolvedFile.url) {
css.setAttribute('href', resolvedFile.url);
} else {
const style = sketchDoc.createElement('style');
style.innerHTML = `\n${resolvedFile.content}`;
sketchDoc.getElementsByTagName("head")[0].appendChild(style);
css.parentNode.removeChild(css);
}
}
}
});
}