diff options
author | mehekj <mehek.jethani@gmail.com> | 2022-03-20 10:29:42 -0400 |
---|---|---|
committer | mehekj <mehek.jethani@gmail.com> | 2022-03-20 10:29:42 -0400 |
commit | 0a5e02a87fdabff5ff8399829ff857cae90fc1e2 (patch) | |
tree | b7c05080dac66366768f23e59a43f62533a22415 /src/client/views/nodes/WebBoxRenderer.js | |
parent | 1f7cf7babc76ecff5aef5fe663c48e067e85dd26 (diff) |
Revert "Merge remote-tracking branch 'origin/speedups2' into temporalmedia-mehek"
This reverts commit 1f7cf7babc76ecff5aef5fe663c48e067e85dd26, reversing
changes made to 1e3ad4de06f83eab54628de660529fefb9a0dc63.
Diffstat (limited to 'src/client/views/nodes/WebBoxRenderer.js')
-rw-r--r-- | src/client/views/nodes/WebBoxRenderer.js | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js deleted file mode 100644 index 08a5746d1..000000000 --- a/src/client/views/nodes/WebBoxRenderer.js +++ /dev/null @@ -1,395 +0,0 @@ -/** - * - * @param {StyleSheetList} styleSheets - */ -var ForeignHtmlRenderer = function (styleSheets) { - - const self = this; - - /** - * - * @param {String} binStr - */ - const binaryStringToBase64 = function (binStr) { - return new Promise(function (resolve) { - const reader = new FileReader(); - reader.readAsDataURL(binStr); - reader.onloadend = function () { - resolve(reader.result); - } - }); - }; - - function prepend(extension) { - return window.location.origin + extension; - } - function CorsProxy(url) { - return prepend("/corsProxy/") + encodeURIComponent(url); - } - /** - * - * @param {String} url - * @returns {Promise} - */ - const getResourceAsBase64 = function (webUrl, inurl) { - return new Promise(function (resolve, reject) { - 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; - var url = inurl; - if (inurl.startsWith("/static")) { - url = (new URL(webUrl).origin + inurl); - } else - if ((inurl.startsWith("/") && !inurl.startsWith("//"))) { - url = CorsProxy(new URL(webUrl).origin + inurl); - } else if (!inurl.startsWith("http") && !inurl.startsWith("//")) { - url = CorsProxy(webUrl + "/" + inurl); - } - xhr.open("GET", url); - xhr.responseType = 'blob'; - - xhr.onreadystatechange = async function () { - if (xhr.readyState === 4 && xhr.status === 200) { - const resBase64 = await binaryStringToBase64(xhr.response); - - resolve( - { - "resourceUrl": inurl, - "resourceBase64": resBase64 - } - ); - } else if (xhr.readyState === 4) { - console.log("COULDN'T FIND: " + (inurl.startsWith("/") ? webUrl + inurl : inurl)); - resolve( - { - "resourceUrl": "", - "resourceBase64": inurl - } - ); - } - }; - - xhr.send(null); - }); - }; - - /** - * - * @param {String[]} urls - * @returns {Promise} - */ - const getMultipleResourcesAsBase64 = function (webUrl, urls) { - const promises = []; - for (let i = 0; i < urls.length; i++) { - promises.push(getResourceAsBase64(webUrl, urls[i])); - } - return Promise.all(promises); - }; - - /** - * - * @param {String} str - * @param {Number} startIndex - * @param {String} prefixToken - * @param {String[]} suffixTokens - * - * @returns {String|null} - */ - const parseValue = function (str, startIndex, prefixToken, suffixTokens) { - const idx = str.indexOf(prefixToken, startIndex); - if (idx === -1) { - return null; - } - - let val = ''; - for (let i = idx + prefixToken.length; i < str.length; i++) { - if (suffixTokens.indexOf(str[i]) !== -1) { - break; - } - - val += str[i]; - } - - return { - "foundAtIndex": idx, - "value": val - } - }; - - /** - * - * @param {String} cssRuleStr - * @returns {String[]} - */ - const getUrlsFromCssString = function (cssRuleStr, selector = "url(", delimiters = [')'], mustEndWithQuote = false) { - const urlsFound = []; - let searchStartIndex = 0; - - while (true) { - const url = parseValue(cssRuleStr, searchStartIndex, selector, delimiters); - if (url === null) { - break; - } - searchStartIndex = url.foundAtIndex + url.value.length; - if (mustEndWithQuote && url.value[url.value.length - 1] !== '"') continue; - const unquoted = removeQuotes(url.value); - if (!unquoted /* || (!unquoted.startsWith('http')&& !unquoted.startsWith("/") )*/ || unquoted === 'http://' || unquoted === 'https://') { - continue; - } - - unquoted && urlsFound.push(unquoted); - } - - return urlsFound; - }; - - /** - * - * @param {String} html - * @returns {String[]} - */ - const getImageUrlsFromFromHtml = function (html) { - return getUrlsFromCssString(html, "src=", [' ', '>', '\t'], true); - }; - const getSourceUrlsFromFromHtml = function (html) { - return getUrlsFromCssString(html, "source=", [' ', '>', '\t'], true); - }; - - /** - * - * @param {String} str - * @returns {String} - */ - const removeQuotes = function (str) { - return str.replace(/["']/g, ""); - }; - - const escapeRegExp = function (string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string - }; - - /** - * - * @param {String} contentHtml - * @param {Number} width - * @param {Number} height - * - * @returns {Promise<String>} - */ - const buildSvgDataUri = async function (webUrl, contentHtml, width, height, scroll) { - - return new Promise(async function (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 = ""; - let urlsFoundInCss = []; - - for (let i = 0; i < styleSheets.length; i++) { - try { - const rules = styleSheets[i].cssRules - for (let j = 0; j < rules.length; j++) { - const cssRuleStr = rules[j].cssText; - urlsFoundInCss.push(...getUrlsFromCssString(cssRuleStr)); - cssStyles += cssRuleStr; - } - } catch (e) { - - } - } - - // 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); - // } - // } - - contentHtml = contentHtml.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 - let urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml); - const fetchedResources = await getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml); - for (let i = 0; i < fetchedResources.length; i++) { - const r = fetchedResources[i]; - if (r.resourceUrl) { - contentHtml = contentHtml.replace(new RegExp(escapeRegExp(r.resourceUrl), "g"), r.resourceBase64); - } - } - - const styleElem = document.createElement("style"); - styleElem.innerHTML = cssStyles.replace(">", ">").replace("<", "<"); - - const styleElemString = new XMLSerializer().serializeToString(styleElem).replace(/>/g, ">").replace(/</g, "<"); - - // create DOM element string that encapsulates styles + content - const contentRootElem = document.createElement("body"); - contentRootElem.style.zIndex = "1111"; - // contentRootElem.style.transform = "scale(0.08)" - contentRootElem.innerHTML = styleElemString + contentHtml; - contentRootElem.setAttribute("xmlns", "http://www.w3.org/1999/xhtml"); - //document.body.appendChild(contentRootElem); - - const contentRootElemString = new XMLSerializer().serializeToString(contentRootElem); - - // build SVG string - const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${width}' height='${height}'> - <foreignObject x='0' y='${-scroll}' width='${width}' height='${scroll + height}'> - ${contentRootElemString} - </foreignObject> - </svg>`; - - // convert SVG to data-uri - const dataUri = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svg)))}`; - - resolve(dataUri); - }); - }; - - /** - * @param {String} html - * @param {Number} width - * @param {Number} height - * - * @return {Promise<Image>} - */ - this.renderToImage = async function (webUrl, html, width, height, scroll) { - return new Promise(async function (resolve, reject) { - const img = new Image(); - console.log("BUILDING SVG for:" + webUrl); - img.src = await buildSvgDataUri(webUrl, html, width, height, scroll); - - img.onload = function () { - console.log("IMAGE SVG created:" + webUrl); - resolve(img); - }; - }); - }; - - /** - * @param {String} html - * @param {Number} width - * @param {Number} height - * - * @return {Promise<Image>} - */ - this.renderToCanvas = async function (webUrl, html, width, height, scroll) { - return new Promise(async function (resolve, reject) { - const img = await self.renderToImage(webUrl, html, width, height, scroll); - - const canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - - const canvasCtx = canvas.getContext('2d'); - canvasCtx.drawImage(img, 0, 0, img.width, img.height); - - resolve(canvas); - }); - }; - - /** - * @param {String} html - * @param {Number} width - * @param {Number} height - * - * @return {Promise<String>} - */ - this.renderToBase64Png = async function (webUrl, html, width, height, scroll) { - return new Promise(async function (resolve, reject) { - const canvas = await self.renderToCanvas(webUrl, html, width, height, scroll); - resolve(canvas.toDataURL('image/png')); - }); - }; - -}; - - -export function CreateImage(webUrl, styleSheets, html, width, height, scroll) { - const val = (new ForeignHtmlRenderer(styleSheets)).renderToBase64Png(webUrl, html.replace(/\n/g, "").replace(/<script((?!\/script).)*<\/script>/g, ""), width, height, scroll); - return val; -} - - - -var ClipboardUtils = new function () { - var permissions = { - 'image/bmp': true, - 'image/gif': true, - 'image/png': true, - 'image/jpeg': true, - 'image/tiff': true - }; - - function getType(types) { - for (var j = 0; j < types.length; ++j) { - var type = types[j]; - if (permissions[type]) { - return type; - } - } - return null; - } - function getItem(items) { - for (var i = 0; i < items.length; ++i) { - var item = items[i]; - if (item) { - var type = getType(item.types); - if (type) { - return item.getType(type); - } - } - } - return null; - } - function loadFile(file, callback) { - if (window.FileReader) { - var reader = new FileReader(); - reader.onload = function () { - callback(reader.result, null); - }; - reader.onerror = function () { - callback(null, 'Incorrect file.'); - }; - reader.readAsDataURL(file); - } else { - callback(null, 'File api is not supported.'); - } - } - this.readImage = function (callback) { - if (navigator.clipboard) { - var promise = navigator.clipboard.read(); - promise - .then(function (items) { - var promise = getItem(items); - if (promise == null) { - callback(null, null); - return; - } - promise - .then(function (result) { - loadFile(result, callback); - }) - .catch(function (error) { - callback(null, 'Reading clipboard error.'); - }); - }) - .catch(function (error) { - callback(null, 'Reading clipboard error.'); - }); - } else { - callback(null, 'Clipboard is not supported.'); - } - }; -}; - - -export function pasteImageBitmap(callback) { - return ClipboardUtils.readImage(callback); -}
\ No newline at end of file |