aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/WebBoxRenderer.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/WebBoxRenderer.js')
-rw-r--r--src/client/views/nodes/WebBoxRenderer.js133
1 files changed, 61 insertions, 72 deletions
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index 914adb404..6fb8f4957 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-undef */
/**
*
* @param {StyleSheetList} styleSheets
@@ -9,15 +10,14 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @param {String} binStr
*/
- const binaryStringToBase64 = function (binStr) {
- return new Promise(resolve => {
+ const binaryStringToBase64 = binStr =>
+ new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(binStr);
reader.onloadend = function () {
resolve(reader.result);
};
});
- };
function prepend(extension) {
return window.location.origin + extension;
@@ -30,8 +30,8 @@ const ForeignHtmlRenderer = function (styleSheets) {
* @param {String} url
* @returns {Promise}
*/
- const getResourceAsBase64 = function (webUrl, inurl) {
- return new Promise((resolve, reject) => {
+ const getResourceAsBase64 = (webUrl, inurl) =>
+ new Promise(resolve => {
const xhr = new XMLHttpRequest();
// const url = inurl.startsWith("/") && !inurl.startsWith("//") ? webUrl + inurl : inurl;
// const url = CorsProxy(inurl.startsWith("/") && !inurl.startsWith("//") ? webUrl + inurl : inurl);// inurl.startsWith("http") ? CorsProxy(inurl) : inurl;
@@ -67,16 +67,15 @@ const ForeignHtmlRenderer = function (styleSheets) {
xhr.send(null);
});
- };
/**
*
* @param {String[]} urls
* @returns {Promise}
*/
- const getMultipleResourcesAsBase64 = function (webUrl, urls) {
+ const getMultipleResourcesAsBase64 = (webUrl, urls) => {
const promises = [];
- for (let i = 0; i < urls.length; i += 1) {
+ for (let i = 0; webUrl && i < urls.length; i += 1) {
promises.push(getResourceAsBase64(webUrl, urls[i]));
}
return Promise.all(promises);
@@ -130,6 +129,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
const urlsFound = [];
let searchStartIndex = 0;
+ // eslint-disable-next-line no-constant-condition
while (true) {
const url = parseValue(cssRuleStr, searchStartIndex, selector, delimiters);
if (url === null) {
@@ -155,9 +155,6 @@ const ForeignHtmlRenderer = function (styleSheets) {
const getImageUrlsFromFromHtml = function (html) {
return getUrlsFromCssString(html, 'src=', [' ', '>', '\t'], true);
};
- const getSourceUrlsFromFromHtml = function (html) {
- return getUrlsFromCssString(html, 'source=', [' ', '>', '\t'], true);
- };
const escapeRegExp = function (string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
@@ -171,46 +168,45 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @returns {Promise<String>}
*/
- const buildSvgDataUri = async function (webUrl, inputContentHtml, width, height, scroll, xoff) {
- return new Promise(async (resolve, reject) => {
- /* !! The problems !!
- * 1. CORS (not really an issue, expect perhaps for images, as this is a general security consideration to begin with)
- * 2. Platform won't wait for external assets to load (fonts, images, etc.)
- */
-
- // copy styles
- let cssStyles = '';
- const urlsFoundInCss = [];
-
- for (let i = 0; i < styleSheets.length; i += 1) {
- try {
- const rules = styleSheets[i].cssRules;
- for (let j = 0; j < rules.length; j += 1) {
- const cssRuleStr = rules[j].cssText;
- urlsFoundInCss.push(...getUrlsFromCssString(cssRuleStr));
- cssStyles += cssRuleStr;
- }
- } catch (e) {
- /* empty */
+ const buildSvgDataUri = (webUrl, inputContentHtml, width, height, scroll, xoff) => {
+ /* !! The problems !!
+ * 1. CORS (not really an issue, expect perhaps for images, as this is a general security consideration to begin with)
+ * 2. Platform won't wait for external assets to load (fonts, images, etc.)
+ */
+
+ // copy styles
+ let cssStyles = '';
+ const urlsFoundInCss = [];
+
+ for (let i = 0; i < styleSheets.length; i += 1) {
+ try {
+ const rules = styleSheets[i].cssRules;
+ for (let j = 0; j < rules.length; j += 1) {
+ const cssRuleStr = rules[j].cssText;
+ urlsFoundInCss.push(...getUrlsFromCssString(cssRuleStr));
+ cssStyles += cssRuleStr;
}
+ } catch (e) {
+ /* empty */
}
+ }
- // const fetchedResourcesFromStylesheets = await getMultipleResourcesAsBase64(webUrl, urlsFoundInCss);
- // for (let i = 0; i < fetchedResourcesFromStylesheets.length; i++) {
- // const r = fetchedResourcesFromStylesheets[i];
- // if (r.resourceUrl) {
- // cssStyles = cssStyles.replace(new RegExp(escapeRegExp(r.resourceUrl), "g"), r.resourceBase64);
- // }
- // }
-
- let contentHtml = inputContentHtml
- .replace(/<source[^>]*>/g, '') // <picture> tags have a <source> which has a srcset field of image refs. instead of converting each, just use the default <img> of the picture
- .replace(/noscript/g, 'div')
- .replace(/<div class="mediaset"><\/div>/g, '') // when scripting isn't available (ie, rendering web pages here), <noscript> tags should become <div>'s. But for Brown CS, there's a layout problem if you leave the empty <mediaset> tag
- .replace(/<link[^>]*>/g, '') // don't need to keep any linked style sheets because we've already processed all style sheets above
- .replace(/srcset="([^ "]*)[^"]*"/g, 'src="$1"'); // instead of converting each item in the srcset to a data url, just convert the first one and use that
- const urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml).filter(url => !url.startsWith('data:'));
- const fetchedResources = webUrl ? await getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml) : [];
+ // const fetchedResourcesFromStylesheets = await getMultipleResourcesAsBase64(webUrl, urlsFoundInCss);
+ // for (let i = 0; i < fetchedResourcesFromStylesheets.length; i++) {
+ // const r = fetchedResourcesFromStylesheets[i];
+ // if (r.resourceUrl) {
+ // cssStyles = cssStyles.replace(new RegExp(escapeRegExp(r.resourceUrl), "g"), r.resourceBase64);
+ // }
+ // }
+
+ let contentHtml = inputContentHtml
+ .replace(/<source[^>]*>/g, '') // <picture> tags have a <source> which has a srcset field of image refs. instead of converting each, just use the default <img> of the picture
+ .replace(/noscript/g, 'div')
+ .replace(/<div class="mediaset"><\/div>/g, '') // when scripting isn't available (ie, rendering web pages here), <noscript> tags should become <div>'s. But for Brown CS, there's a layout problem if you leave the empty <mediaset> tag
+ .replace(/<link[^>]*>/g, '') // don't need to keep any linked style sheets because we've already processed all style sheets above
+ .replace(/srcset="([^ "]*)[^"]*"/g, 'src="$1"'); // instead of converting each item in the srcset to a data url, just convert the first one and use that
+ const urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml).filter(url => !url.startsWith('data:'));
+ return getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml).then(fetchedResources => {
for (let i = 0; i < fetchedResources.length; i += 1) {
const r = fetchedResources[i];
if (r.resourceUrl) {
@@ -243,9 +239,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
</svg>`;
// convert SVG to data-uri
- const dataUri = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svg)))}`;
-
- resolve(dataUri);
+ return `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svg)))}`;
});
};
@@ -256,18 +250,19 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<Image>}
*/
- this.renderToImage = async function (webUrl, html, width, height, scroll, xoff) {
- return new Promise(async (resolve, reject) => {
+ this.renderToImage = (webUrl, html, width, height, scroll, xoff) =>
+ new Promise(resolve => {
const img = new Image();
- console.log(`BUILDING SVG for: ${webUrl}`);
- img.src = await buildSvgDataUri(webUrl, html, width, height, scroll, xoff);
-
img.onload = function () {
console.log(`IMAGE SVG created: ${webUrl}`);
resolve(img);
};
+ console.log(`BUILDING SVG for: ${webUrl}`);
+ buildSvgDataUri(webUrl, html, width, height, scroll, xoff).then(uri => {
+ img.src = uri;
+ return img;
+ });
});
- };
/**
* @param {String} html
@@ -276,20 +271,16 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<Image>}
*/
- this.renderToCanvas = async function (webUrl, html, width, height, scroll, xoff, oversample) {
- return new Promise(async (resolve, reject) => {
- const img = await self.renderToImage(webUrl, html, width, height, scroll, xoff);
-
+ this.renderToCanvas = (webUrl, html, width, height, scroll, xoff, oversample) =>
+ self.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => {
const canvas = document.createElement('canvas');
canvas.width = img.width * oversample;
canvas.height = img.height * oversample;
const canvasCtx = canvas.getContext('2d');
canvasCtx.drawImage(img, 0, 0, img.width * oversample, img.height * oversample);
-
- resolve(canvas);
+ return canvas;
});
- };
/**
* @param {String} html
@@ -298,12 +289,10 @@ const ForeignHtmlRenderer = function (styleSheets) {
*
* @return {Promise<String>}
*/
- this.renderToBase64Png = async function (webUrl, html, width, height, scroll, xoff, oversample) {
- return new Promise(async (resolve, reject) => {
- const canvas = await self.renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample);
- resolve(canvas.toDataURL('image/png'));
- });
- };
+ this.renderToBase64Png = (webUrl, html, width, height, scroll, xoff, oversample) =>
+ self
+ .renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) //
+ .then(canvas => canvas.toDataURL('image/png'));
};
export function CreateImage(webUrl, styleSheets, html, width, height, scroll, xoff = 0, oversample = 1) {
@@ -379,11 +368,11 @@ const ClipboardUtils = new (function () {
.then(result => {
loadFile(result, callback);
})
- .catch(error => {
+ .catch(() => {
callback(null, 'Reading clipboard error.');
});
})
- .catch(error => {
+ .catch(() => {
callback(null, 'Reading clipboard error.');
});
} else {