mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #44 - WebAssembly GC support, fix more WebRTC bugs
This commit is contained in:
523
sources/wasm-gc-teavm/js/platformWebView.js
Normal file
523
sources/wasm-gc-teavm/js/platformWebView.js
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
const platfWebViewName = "platformWebView";
|
||||
|
||||
function initializePlatfWebView(webViewImports) {
|
||||
|
||||
const BEGIN_SHOWING_DIRECT = 0;
|
||||
const BEGIN_SHOWING_ENABLE_JAVASCRIPT = 1;
|
||||
const BEGIN_SHOWING_CONTENT_BLOCKED = 2;
|
||||
|
||||
const EVENT_WEBVIEW_CHANNEL = 0;
|
||||
const EVENT_WEBVIEW_MESSAGE = 1;
|
||||
const EVENT_WEBVIEW_PERMISSION_ALLOW = 2;
|
||||
const EVENT_WEBVIEW_PERMISSION_BLOCK = 3;
|
||||
const EVENT_WEBVIEW_PERMISSION_CLEAR = 4;
|
||||
|
||||
const EVENT_CHANNEL_OPEN = 0;
|
||||
const EVENT_CHANNEL_CLOSE = 1;
|
||||
|
||||
const EVENT_MESSAGE_STRING = 0;
|
||||
const EVENT_MESSAGE_BINARY = 1;
|
||||
|
||||
const utf8Decoder = new TextDecoder("utf-8");
|
||||
|
||||
var supported = false;
|
||||
var cspSupport = false;
|
||||
var supportForce = runtimeOpts.forceWebViewSupport;
|
||||
var enableCSP = runtimeOpts.enableWebViewCSP;
|
||||
if(supportForce) {
|
||||
supported = true;
|
||||
cspSupport = true;
|
||||
}else {
|
||||
supported = false;
|
||||
cspSupport = false;
|
||||
try {
|
||||
var tmp = /** @type {HTMLIFrameElement} */ (document.createElement("iframe"));
|
||||
supported = tmp != null && (typeof tmp.allow === "string") && (typeof tmp.sandbox === "object");
|
||||
cspSupport = enableCSP && supported && (typeof tmp.csp === "string");
|
||||
}catch(ex) {
|
||||
eagError("Error checking iframe support");
|
||||
eagError(ex);
|
||||
}
|
||||
}
|
||||
if(!supported) {
|
||||
eagError("This browser does not meet the safety requirements for webview support, this feature will be disabled");
|
||||
}else if(!cspSupport && enableCSP) {
|
||||
eagWarn("This browser does not support CSP attribute on iframes! (try Chrome)");
|
||||
}
|
||||
|
||||
const requireSSL = location.protocol && "https:" === location.protocol.toLowerCase();
|
||||
|
||||
var webviewResetSerial = 0;
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
var currentIFrameContainer = null;
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
var currentAllowJavaScript = null;
|
||||
|
||||
/** @type {HTMLIFrameElement} */
|
||||
var currentIFrame = null;
|
||||
|
||||
/** @type {function(MessageEvent)|null} */
|
||||
var currentMessageHandler = null;
|
||||
|
||||
window.addEventListener("message", /** @type {function(Event)} */ (function(/** MessageEvent */ evt) {
|
||||
if(currentMessageHandler && evt.source !== window) {
|
||||
currentMessageHandler(evt);
|
||||
}
|
||||
}));
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
webViewImports["checkSupported"] = function() {
|
||||
return supported;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
webViewImports["checkCSPSupported"] = function() {
|
||||
return cspSupport;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} ch
|
||||
* @param {string} str
|
||||
*/
|
||||
webViewImports["sendStringMessage"] = function(ch, str) {
|
||||
try {
|
||||
var w;
|
||||
if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) {
|
||||
w.postMessage({
|
||||
"ver": 1,
|
||||
"channel": ch,
|
||||
"type": "string",
|
||||
"data": str
|
||||
}, "*");
|
||||
}else {
|
||||
eagError("Server tried to send the WebView a message, but the message channel is not open!");
|
||||
}
|
||||
}catch(/** Error */ ex) {
|
||||
eagStackTrace(ERROR, "Failed to send string message to WebView!", ex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} ch
|
||||
* @param {Uint8Array} bin
|
||||
*/
|
||||
webViewImports["sendBinaryMessage"] = function(ch, bin) {
|
||||
try {
|
||||
var w;
|
||||
if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) {
|
||||
const copiedArray = new Uint8Array(bin.length);
|
||||
copiedArray.set(bin, 0);
|
||||
w.postMessage({
|
||||
"ver": 1,
|
||||
"channel": ch,
|
||||
"type": "binary",
|
||||
"data": copiedArray.buffer
|
||||
}, "*");
|
||||
}else {
|
||||
eagError("Server tried to send the WebView a message, but the message channel is not open!");
|
||||
}
|
||||
}catch(/** Error */ ex) {
|
||||
eagStackTrace(ERROR, "Failed to send string message to WebView!", ex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} state
|
||||
* @param {Object} options
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
webViewImports["beginShowing"] = function(state, options, x, y, w, h) {
|
||||
if(!supported) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setupShowing(x, y, w, h);
|
||||
switch(state) {
|
||||
case BEGIN_SHOWING_DIRECT:
|
||||
beginShowingDirect(options);
|
||||
break;
|
||||
case BEGIN_SHOWING_ENABLE_JAVASCRIPT:
|
||||
if(options["contentMode"] === 1) {
|
||||
const copiedBlob = new Uint8Array(options["blob"].length);
|
||||
copiedBlob.set(options["blob"], 0);
|
||||
options["blob"] = copiedBlob;
|
||||
}
|
||||
beginShowingEnableJavaScript(options);
|
||||
break;
|
||||
case BEGIN_SHOWING_CONTENT_BLOCKED:
|
||||
if(options["contentMode"] === 1) {
|
||||
const copiedBlob = new Uint8Array(options["blob"].length);
|
||||
copiedBlob.set(options["blob"], 0);
|
||||
options["blob"] = copiedBlob;
|
||||
}
|
||||
beginShowingContentBlocked(options);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}catch(/** Error */ ex) {
|
||||
eagStackTrace(ERROR, "Failed to begin showing WebView!", ex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
function setupShowing(x, y, w, h) {
|
||||
if(currentIFrameContainer !== null) {
|
||||
endShowingImpl();
|
||||
}
|
||||
currentIFrameContainer = /** @type {HTMLElement} */ (document.createElement("div"));
|
||||
currentIFrameContainer.classList.add("_eaglercraftX_webview_container_element");
|
||||
currentIFrameContainer.style.border = "5px solid #333333";
|
||||
currentIFrameContainer.style.zIndex = "11";
|
||||
currentIFrameContainer.style.position = "absolute";
|
||||
currentIFrameContainer.style.backgroundColor = "#DDDDDD";
|
||||
currentIFrameContainer.style.fontFamily = "sans-serif";
|
||||
resizeImpl(x, y, w, h);
|
||||
parentElement.appendChild(currentIFrameContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLIFrameElement} iframeElement
|
||||
* @param {string} str
|
||||
*/
|
||||
function setAllowSafe(iframeElement, str) {
|
||||
iframeElement.allow = str;
|
||||
return iframeElement.allow === str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLIFrameElement} iframeElement
|
||||
* @param {Array<string>} args
|
||||
*/
|
||||
function setSandboxSafe(iframeElement, args) {
|
||||
const theSandbox = iframeElement.sandbox;
|
||||
for(var i = 0; i < args.length; ++i) {
|
||||
theSandbox.add(args[i]);
|
||||
}
|
||||
for(var i = 0; i < args.length; ++i) {
|
||||
if(!theSandbox.contains(args[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < theSandbox.length; ++i) {
|
||||
if(!args.find(itm => itm === theSandbox[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function beginShowingDirect(options) {
|
||||
if(!supportForce) {
|
||||
currentIFrame = /** @type {HTMLIFrameElement} */ (document.createElement("iframe"));
|
||||
currentIFrame.referrerPolicy = "strict-origin";
|
||||
const sandboxArgs = [ "allow-downloads" ];
|
||||
if(options["scriptEnabled"]) {
|
||||
sandboxArgs.push("allow-scripts");
|
||||
sandboxArgs.push("allow-pointer-lock");
|
||||
}
|
||||
if(!setAllowSafe(currentIFrame, "") || !setSandboxSafe(currentIFrame, sandboxArgs)) {
|
||||
eagError("Caught safety exception while opening webview!");
|
||||
if(currentIFrame !== null) {
|
||||
currentIFrame.remove();
|
||||
currentIFrame = null;
|
||||
}
|
||||
eagError("Things you can try:");
|
||||
eagError("1. Set window.eaglercraftXOpts.forceWebViewSupport to true");
|
||||
eagError("2. Set window.eaglercraftXOpts.enableWebViewCSP to false");
|
||||
eagError("(these settings may compromise security)");
|
||||
beginShowingSafetyError();
|
||||
return;
|
||||
}
|
||||
}else {
|
||||
currentIFrame = /** @type {HTMLIFrameElement} */ (document.createElement("iframe"));
|
||||
currentIFrame.allow = "";
|
||||
currentIFrame.referrerPolicy = "strict-origin";
|
||||
currentIFrame.sandbox.add("allow-downloads");
|
||||
if(options["scriptEnabled"]) {
|
||||
currentIFrame.sandbox.add("allow-scripts");
|
||||
currentIFrame.sandbox.add("allow-pointer-lock");
|
||||
}
|
||||
}
|
||||
currentIFrame.credentialless = true;
|
||||
currentIFrame.loading = "lazy";
|
||||
var cspWarn = false;
|
||||
if(options["contentMode"] === 1) {
|
||||
if(enableCSP && cspSupport) {
|
||||
if(typeof currentIFrame.csp === "string") {
|
||||
var csp = "default-src 'none';";
|
||||
var protos = options["strictCSPEnable"] ? "" : (requireSSL ? " https:" : " http: https:");
|
||||
if(options["scriptEnabled"]) {
|
||||
csp += (" script-src 'unsafe-eval' 'unsafe-inline' data: blob:" + protos + ";");
|
||||
csp += (" style-src 'unsafe-eval' 'unsafe-inline' data: blob:" + protos + ";");
|
||||
csp += (" img-src data: blob:" + protos + ";");
|
||||
csp += (" font-src data: blob:" + protos + ";");
|
||||
csp += (" child-src data: blob:" + protos + ";");
|
||||
csp += (" frame-src data: blob:;");
|
||||
csp += (" media-src data: mediastream: blob:" + protos + ";");
|
||||
csp += (" connect-src data: blob:" + protos + ";");
|
||||
csp += (" worker-src data: blob:" + protos + ";");
|
||||
}else {
|
||||
csp += (" style-src data: 'unsafe-inline'" + protos + ";");
|
||||
csp += (" img-src data:" + protos + ";");
|
||||
csp += (" font-src data:" + protos + ";");
|
||||
csp += (" media-src data:" + protos + ";");
|
||||
}
|
||||
currentIFrame.csp = csp;
|
||||
}else {
|
||||
eagWarn("This browser does not support CSP attribute on iframes! (try Chrome)");
|
||||
cspWarn = true;
|
||||
}
|
||||
}else {
|
||||
cspWarn = true;
|
||||
}
|
||||
if(cspWarn && options["strictCSPEnable"]) {
|
||||
eagWarn("Strict CSP was requested for this webview, but that feature is not available!");
|
||||
}
|
||||
}else {
|
||||
cspWarn = true;
|
||||
}
|
||||
currentIFrame.style.border = "none";
|
||||
currentIFrame.style.backgroundColor = "white";
|
||||
currentIFrame.style.width = "100%";
|
||||
currentIFrame.style.height = "100%";
|
||||
currentIFrame.classList.add("_eaglercraftX_webview_iframe_element");
|
||||
currentIFrameContainer.appendChild(currentIFrame);
|
||||
if(options["contentMode"] === 1) {
|
||||
const decodedText = utf8Decoder.decode(options["blob"]);
|
||||
options["blob"] = null;
|
||||
currentIFrame.srcdoc = decodedText;
|
||||
}else {
|
||||
currentIFrame.src = options["uri"];
|
||||
}
|
||||
const resetSer = webviewResetSerial;
|
||||
const curIFrame = currentIFrame;
|
||||
let focusTracker = false;
|
||||
currentIFrame.addEventListener("mouseover", function(/** Event */ evt) {
|
||||
if(resetSer === webviewResetSerial && curIFrame === currentIFrame) {
|
||||
if(!focusTracker) {
|
||||
focusTracker = true;
|
||||
currentIFrame.contentWindow.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
currentIFrame.addEventListener("mouseout", function(/** Event */ evt) {
|
||||
if(resetSer === webviewResetSerial && curIFrame === currentIFrame) {
|
||||
if(focusTracker) {
|
||||
focusTracker = false;
|
||||
window.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
if(options["scriptEnabled"] && options["serverMessageAPIEnabled"]) {
|
||||
currentMessageHandler = function(/** MessageEvent */ evt) {
|
||||
if(resetSer === webviewResetSerial && curIFrame === currentIFrame && evt.source === curIFrame.contentWindow) {
|
||||
/** @type {Object} */
|
||||
const obj = evt.data;
|
||||
if((typeof obj === "object") && (obj["ver"] === 1) && ((typeof obj["channel"] === "string") && obj["channel"]["length"] > 0)) {
|
||||
if(typeof obj["open"] === "boolean") {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_CHANNEL, {
|
||||
"eventType": (obj["open"] ? EVENT_CHANNEL_OPEN : EVENT_CHANNEL_CLOSE),
|
||||
"channelName": obj["channel"]
|
||||
});
|
||||
return;
|
||||
}else if(typeof obj["data"] === "string") {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_MESSAGE, {
|
||||
"eventType": EVENT_MESSAGE_STRING,
|
||||
"channelName": obj["channel"],
|
||||
"eventData": obj["data"]
|
||||
});
|
||||
return;
|
||||
}else if(obj["data"] instanceof ArrayBuffer) {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_MESSAGE, {
|
||||
"eventType": EVENT_MESSAGE_BINARY,
|
||||
"channelName": obj["channel"],
|
||||
"eventData": obj["data"]
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
eagWarn("WebView sent an invalid message!");
|
||||
}else {
|
||||
eagWarn("Recieved message from on dead IFrame handler: (#{}) {}", resetSer, curIFrame.src);
|
||||
}
|
||||
};
|
||||
}
|
||||
eagInfo("WebView is loading: \"{}\"", options["contentMode"] === 1 ? "about:srcdoc" : currentIFrame.src);
|
||||
eagInfo("JavaScript: {}, Strict CSP: {}, Message API: {}", options["scriptEnabled"],
|
||||
options["strictCSPEnable"] && !cspWarn, options["serverMessageAPIEnabled"]);
|
||||
}
|
||||
|
||||
function beginShowingEnableJSSetup() {
|
||||
if(currentAllowJavaScript !== null) {
|
||||
++webviewResetSerial;
|
||||
currentAllowJavaScript.remove();
|
||||
currentAllowJavaScript = null;
|
||||
}
|
||||
currentAllowJavaScript = /** @type {HTMLElement} */ (document.createElement("div"));
|
||||
currentAllowJavaScript.style.backgroundColor = "white";
|
||||
currentAllowJavaScript.style.width = "100%";
|
||||
currentAllowJavaScript.style.height = "100%";
|
||||
currentAllowJavaScript.classList.add("_eaglercraftX_webview_permission_screen");
|
||||
currentIFrameContainer.appendChild(currentAllowJavaScript);
|
||||
}
|
||||
|
||||
function beginShowingEnableJavaScript(options) {
|
||||
beginShowingEnableJSSetup();
|
||||
var strictCSPMarkup;
|
||||
if(options["contentMode"] !== 1) {
|
||||
strictCSPMarkup = "<span style=\"color:red;\">Impossible</span>";
|
||||
}else if(!cspSupport || !enableCSP) {
|
||||
strictCSPMarkup = "<span style=\"color:red;\">Unsupported</span>";
|
||||
}else if(options["strictCSPEnable"]) {
|
||||
strictCSPMarkup = "<span style=\"color:green;\">Enabled</span>";
|
||||
}else {
|
||||
strictCSPMarkup = "<span style=\"color:red;\">Disabled</span>";
|
||||
}
|
||||
var messageAPIMarkup;
|
||||
if(options["serverMessageAPIEnabled"]) {
|
||||
messageAPIMarkup = "<span style=\"color:red;\">Enabled</span>";
|
||||
}else {
|
||||
messageAPIMarkup = "<span style=\"color:green;\">Disabled</span>";
|
||||
}
|
||||
currentAllowJavaScript.innerHTML =
|
||||
"<div style=\"padding-top:13vh;\"><div style=\"margin:auto;max-width:450px;border:6px double black;text-align:center;padding:20px;\">"
|
||||
+ "<h2><img width=\"32\" height=\"32\" style=\"vertical-align:middle;\" src=\"" + faviconURL + "\"> Allow JavaScript</h2>"
|
||||
+ "<p style=\"font-family:monospace;text-decoration:underline;word-wrap:break-word;\" class=\"_eaglercraftX_permission_target_url\"></p>"
|
||||
+ "<h4 style=\"line-height:1.4em;\">Strict CSP: " + strictCSPMarkup + " | "
|
||||
+ "Message API: " + messageAPIMarkup + "</h4>"
|
||||
+ "<p><input class=\"_eaglercraftX_remember_javascript\" type=\"checkbox\" checked> Remember my choice</p>"
|
||||
+ "<p><button style=\"font-size:1.5em;\" class=\"_eaglercraftX_allow_javascript\">Allow</button> "
|
||||
+ "<button style=\"font-size:1.5em;\" class=\"_eaglercraftX_block_javascript\">Block</button></p></div></div>";
|
||||
const serial = webviewResetSerial;
|
||||
if(options["contentMode"] !== 1) {
|
||||
const urlStr = options["url"];
|
||||
currentAllowJavaScript.querySelector("._eaglercraftX_permission_target_url").innerText = urlStr.length() > 255 ? (urlStr.substring(0, 253) + "...") : urlStr;
|
||||
}
|
||||
currentAllowJavaScript.querySelector("._eaglercraftX_allow_javascript").addEventListener("click", function(/** Event */ evt) {
|
||||
if(webviewResetSerial === serial && currentAllowJavaScript !== null) {
|
||||
const chkbox = currentAllowJavaScript.querySelector("._eaglercraftX_remember_javascript");
|
||||
if(chkbox !== null && chkbox.checked) {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_PERMISSION_ALLOW, null);
|
||||
}
|
||||
currentAllowJavaScript.remove();
|
||||
currentAllowJavaScript = null;
|
||||
++webviewResetSerial;
|
||||
beginShowingDirect(options);
|
||||
}
|
||||
});
|
||||
currentAllowJavaScript.querySelector("._eaglercraftX_block_javascript").addEventListener("click", function(/** Event */ evt) {
|
||||
if(webviewResetSerial === serial && currentAllowJavaScript !== null) {
|
||||
const chkbox = currentAllowJavaScript.querySelector("._eaglercraftX_remember_javascript");
|
||||
if(chkbox !== null && chkbox.checked) {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_PERMISSION_BLOCK, null);
|
||||
}
|
||||
beginShowingContentBlocked(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function beginShowingContentBlocked(options) {
|
||||
beginShowingEnableJSSetup();
|
||||
currentAllowJavaScript.innerHTML =
|
||||
"<div style=\"padding-top:13vh;\"><h1 style=\"text-align:center;\">"
|
||||
+ "<img width=\"48\" height=\"48\" style=\"vertical-align:middle;\" src=\"" + faviconURL + "\"> Content Blocked</h1>"
|
||||
+ "<h4 style=\"text-align:center;\">You chose to block JavaScript execution for this embed</h4>"
|
||||
+ "<p style=\"text-align:center;\"><button style=\"font-size:1.0em;\" class=\"_eaglercraftX_re_evaluate_javascript\">Re-evaluate</button></p></div>";
|
||||
const serial = webviewResetSerial;
|
||||
currentAllowJavaScript.querySelector("._eaglercraftX_re_evaluate_javascript").addEventListener("click", function(/** Event */ evt) {
|
||||
if(webviewResetSerial === serial && currentAllowJavaScript !== null) {
|
||||
pushEvent(EVENT_TYPE_WEBVIEW, EVENT_WEBVIEW_PERMISSION_CLEAR, null);
|
||||
beginShowingEnableJavaScript(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function beginShowingSafetyError() {
|
||||
beginShowingEnableJSSetup();
|
||||
currentAllowJavaScript.innerHTML =
|
||||
"<div style=\"padding-top:13vh;\"><h1 style=\"text-align:center;\">"
|
||||
+ "<img width=\"48\" height=\"48\" style=\"vertical-align:middle;\" src=\"" + faviconURL + "\"> IFrame Safety Error</h1>"
|
||||
+ "<h4 style=\"text-align:center;\">The content cannot be displayed safely!</h4>"
|
||||
+ "<h4 style=\"text-align:center;\">Check console for more details</h4></div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} w
|
||||
* @param {number} h
|
||||
*/
|
||||
function resizeImpl(x, y, w, h) {
|
||||
if(currentIFrameContainer) {
|
||||
const s = window.devicePixelRatio;
|
||||
currentIFrameContainer.style.top = "" + (y / s) + "px";
|
||||
currentIFrameContainer.style.left = "" + (x / s) + "px";
|
||||
currentIFrameContainer.style.width = "" + ((w / s) - 10) + "px";
|
||||
currentIFrameContainer.style.height = "" + ((h / s) - 10) + "px";
|
||||
}
|
||||
}
|
||||
|
||||
function endShowingImpl() {
|
||||
++webviewResetSerial;
|
||||
if(currentIFrame) {
|
||||
currentIFrame.remove();
|
||||
currentIFrame = null;
|
||||
}
|
||||
currentMessageHandler = null;
|
||||
if(currentAllowJavaScript) {
|
||||
currentAllowJavaScript.remove();
|
||||
currentAllowJavaScript = null;
|
||||
}
|
||||
if(currentIFrameContainer) {
|
||||
currentIFrameContainer.remove();
|
||||
currentIFrameContainer = null;
|
||||
}
|
||||
window.focus();
|
||||
}
|
||||
|
||||
webViewImports["resize"] = resizeImpl;
|
||||
|
||||
webViewImports["endShowing"] = endShowingImpl;
|
||||
|
||||
}
|
||||
|
||||
function initializeNoPlatfWebView(webViewImports) {
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "checkSupported");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "checkCSPSupported");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "sendStringMessage");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "sendBinaryMessage");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "beginShowing");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "resize");
|
||||
setUnsupportedFunc(webViewImports, platfWebViewName, "endShowing");
|
||||
}
|
Reference in New Issue
Block a user