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.js185
1 files changed, 92 insertions, 93 deletions
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index f3f1bcf5c..20554b858 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -1,14 +1,13 @@
/**
- *
- * @param {StyleSheetList} styleSheets
+ *
+ * @param {StyleSheetList} styleSheets
*/
var ForeignHtmlRenderer = function (styleSheets) {
-
const self = this;
/**
- *
- * @param {String} binStr
+ *
+ * @param {String} binStr
*/
const binaryStringToBase64 = function (binStr) {
return new Promise(function (resolve) {
@@ -16,7 +15,7 @@ var ForeignHtmlRenderer = function (styleSheets) {
reader.readAsDataURL(binStr);
reader.onloadend = function () {
resolve(reader.result);
- }
+ };
});
};
@@ -24,11 +23,11 @@ var ForeignHtmlRenderer = function (styleSheets) {
return window.location.origin + extension;
}
function CorsProxy(url) {
- return prepend("/corsProxy/") + encodeURIComponent(url);
+ return prepend('/corsProxy/') + encodeURIComponent(url);
}
/**
- *
- * @param {String} url
+ *
+ * @param {String} url
* @returns {Promise}
*/
const getResourceAsBase64 = function (webUrl, inurl) {
@@ -37,35 +36,30 @@ var ForeignHtmlRenderer = function (styleSheets) {
//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);
+ 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
- }
- );
+ resolve({
+ resourceUrl: inurl,
+ resourceBase64: resBase64,
+ });
} else if (xhr.readyState === 4) {
- console.log("COULDN'T FIND: " + (inurl.startsWith("/") ? webUrl + inurl : inurl));
- resolve(
- {
- "resourceUrl": "",
- "resourceBase64": inurl
- }
- );
+ console.log("COULDN'T FIND: " + (inurl.startsWith('/') ? webUrl + inurl : inurl));
+ resolve({
+ resourceUrl: '',
+ resourceBase64: inurl,
+ });
}
};
@@ -74,8 +68,8 @@ var ForeignHtmlRenderer = function (styleSheets) {
};
/**
- *
- * @param {String[]} urls
+ *
+ * @param {String[]} urls
* @returns {Promise}
*/
const getMultipleResourcesAsBase64 = function (webUrl, urls) {
@@ -87,13 +81,13 @@ var ForeignHtmlRenderer = function (styleSheets) {
};
/**
- *
- * @param {String} str
- * @param {Number} startIndex
- * @param {String} prefixToken
+ *
+ * @param {String} str
+ * @param {Number} startIndex
+ * @param {String} prefixToken
* @param {String[]} suffixTokens
- *
- * @returns {String|null}
+ *
+ * @returns {String|null}
*/
const parseValue = function (str, startIndex, prefixToken, suffixTokens) {
const idx = str.indexOf(prefixToken, startIndex);
@@ -111,17 +105,17 @@ var ForeignHtmlRenderer = function (styleSheets) {
}
return {
- "foundAtIndex": idx,
- "value": val
- }
+ foundAtIndex: idx,
+ value: val,
+ };
};
/**
- *
- * @param {String} cssRuleStr
+ *
+ * @param {String} cssRuleStr
* @returns {String[]}
*/
- const getUrlsFromCssString = function (cssRuleStr, selector = "url(", delimiters = [')'], mustEndWithQuote = false) {
+ const getUrlsFromCssString = function (cssRuleStr, selector = 'url(', delimiters = [')'], mustEndWithQuote = false) {
const urlsFound = [];
let searchStartIndex = 0;
@@ -133,7 +127,7 @@ var ForeignHtmlRenderer = function (styleSheets) {
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://') {
+ if (!unquoted /* || (!unquoted.startsWith('http')&& !unquoted.startsWith("/") )*/ || unquoted === 'http://' || unquoted === 'https://') {
continue;
}
@@ -144,24 +138,24 @@ var ForeignHtmlRenderer = function (styleSheets) {
};
/**
- *
- * @param {String} html
+ *
+ * @param {String} html
* @returns {String[]}
*/
const getImageUrlsFromFromHtml = function (html) {
- return getUrlsFromCssString(html, "src=", [' ', '>', '\t'], true);
+ return getUrlsFromCssString(html, 'src=', [' ', '>', '\t'], true);
};
const getSourceUrlsFromFromHtml = function (html) {
- return getUrlsFromCssString(html, "source=", [' ', '>', '\t'], true);
+ return getUrlsFromCssString(html, 'source=', [' ', '>', '\t'], true);
};
/**
- *
+ *
* @param {String} str
* @returns {String}
*/
const removeQuotes = function (str) {
- return str.replace(/["']/g, "");
+ return str.replace(/["']/g, '');
};
const escapeRegExp = function (string) {
@@ -169,37 +163,33 @@ var ForeignHtmlRenderer = function (styleSheets) {
};
/**
- *
- * @param {String} contentHtml
+ *
+ * @param {String} contentHtml
* @param {Number} width
* @param {Number} height
- *
+ *
* @returns {Promise<String>}
*/
const buildSvgDataUri = async function (webUrl, contentHtml, width, height, scroll, xoff) {
-
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.)
- */
+ * 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 cssStyles = '';
let urlsFoundInCss = [];
for (let i = 0; i < styleSheets.length; i++) {
try {
- const rules = styleSheets[i].cssRules
+ 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) {
-
- }
+ } catch (e) {}
}
// const fetchedResourcesFromStylesheets = await getMultipleResourcesAsBase64(webUrl, urlsFoundInCss);
@@ -210,30 +200,34 @@ var ForeignHtmlRenderer = function (styleSheets) {
// }
// }
- 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).filter(url => !url.startsWith("data:"));
+ 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).filter(url => !url.startsWith('data:'));
const fetchedResources = webUrl ? 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);
+ contentHtml = contentHtml.replace(new RegExp(escapeRegExp(r.resourceUrl), 'g'), r.resourceBase64);
}
}
- const styleElem = document.createElement("style");
- styleElem.innerHTML = cssStyles.replace("&gt;", ">").replace("&lt;", "<");
+ const styleElem = document.createElement('style');
+ styleElem.innerHTML =
+ '#mw-sidebar-checkbox ~ .vector-main-menu-container { display: none !important; } ' + // hack to prevent wikipedia menu from appearing
+ cssStyles.replace('&gt;', '>').replace('&lt;', '<');
- const styleElemString = new XMLSerializer().serializeToString(styleElem).replace(/&gt;/g, ">").replace(/&lt;/g, "<");
+ const styleElemString = new XMLSerializer().serializeToString(styleElem).replace(/&gt;/g, '>').replace(/&lt;/g, '<');
// create DOM element string that encapsulates styles + content
- const contentRootElem = document.createElement("body");
- contentRootElem.style.zIndex = "1111";
+ 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");
+ contentRootElem.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
//document.body.appendChild(contentRootElem);
const contentRootElemString = new XMLSerializer().serializeToString(contentRootElem);
@@ -256,17 +250,17 @@ var ForeignHtmlRenderer = function (styleSheets) {
* @param {String} html
* @param {Number} width
* @param {Number} height
- *
+ *
* @return {Promise<Image>}
*/
this.renderToImage = async function (webUrl, html, width, height, scroll, xoff) {
return new Promise(async function (resolve, reject) {
const img = new Image();
- console.log("BUILDING SVG for:" + webUrl);
+ 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);
+ console.log('IMAGE SVG created:' + webUrl);
resolve(img);
};
});
@@ -276,7 +270,7 @@ var ForeignHtmlRenderer = function (styleSheets) {
* @param {String} html
* @param {Number} width
* @param {Number} height
- *
+ *
* @return {Promise<Image>}
*/
this.renderToCanvas = async function (webUrl, html, width, height, scroll, xoff, oversample) {
@@ -298,7 +292,7 @@ var ForeignHtmlRenderer = function (styleSheets) {
* @param {String} html
* @param {Number} width
* @param {Number} height
- *
+ *
* @return {Promise<String>}
*/
this.renderToBase64Png = async function (webUrl, html, width, height, scroll, xoff, oversample) {
@@ -307,24 +301,30 @@ var ForeignHtmlRenderer = function (styleSheets) {
resolve(canvas.toDataURL('image/png'));
});
};
-
};
-
export function CreateImage(webUrl, styleSheets, html, width, height, scroll, xoff = 0, oversample = 1) {
- const val = (new ForeignHtmlRenderer(styleSheets)).renderToBase64Png(webUrl, html.replace(/docView-hack/g, 'documentView-hack').replace(/\n/g, "").replace(/<script((?!\/script).)*<\/script>/g, ""), width, height, scroll, xoff, oversample);
- return val;
+ return new ForeignHtmlRenderer(styleSheets).renderToBase64Png(
+ webUrl,
+ html
+ .replace(/docView-hack/g, 'documentView-hack')
+ .replace(/\n/g, '')
+ .replace(/<script((?!\/script).)*<\/script>/g, ''),
+ width,
+ height,
+ scroll,
+ xoff,
+ oversample
+ );
}
-
-
-var ClipboardUtils = new function () {
+var ClipboardUtils = new (function () {
var permissions = {
'image/bmp': true,
'image/gif': true,
'image/png': true,
'image/jpeg': true,
- 'image/tiff': true
+ 'image/tiff': true,
};
function getType(types) {
@@ -387,9 +387,8 @@ var ClipboardUtils = new function () {
callback(null, 'Clipboard is not supported.');
}
};
-};
-
+})();
export function pasteImageBitmap(callback) {
return ClipboardUtils.readImage(callback);
-} \ No newline at end of file
+}