aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/WebBoxRenderer.js
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-04-25 17:15:20 -0400
committerbobzel <zzzman@gmail.com>2024-04-25 17:15:20 -0400
commitd6720fa48d78cc313d6418acd8cbdaeda965285c (patch)
treed9cec7f7b031b20bfc5423bc48f8791074b2d5c1 /src/client/views/nodes/WebBoxRenderer.js
parentbd3b34cce2ad85bfc96c16304b532d1510fd359e (diff)
changed marqueeAnnotator to save inline annotations as text strings instead of Docs. enabled making image crops of text selections on PDFs. cleaned up webboxrendered lint promses, and Annotation render
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 {