589 lines
28 KiB
JavaScript
589 lines
28 KiB
JavaScript
window.flutter_inappwebview = {
|
|
webViews: {},
|
|
createFlutterInAppWebView: function(viewId, iframeId) {
|
|
var webView = {
|
|
viewId: viewId,
|
|
iframeId: iframeId,
|
|
iframe: null,
|
|
iframeContainer: null,
|
|
windowAutoincrementId: 0,
|
|
windows: {},
|
|
isFullscreen: false,
|
|
documentTitle: null,
|
|
functionMap: {},
|
|
settings: {},
|
|
disableContextMenuHandler: function(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
return false;
|
|
},
|
|
prepare: function(settings) {
|
|
webView.settings = settings;
|
|
var iframe = document.getElementById(iframeId);
|
|
var iframeContainer = document.getElementById(iframeId + '-container');
|
|
|
|
document.addEventListener('fullscreenchange', function(event) {
|
|
// document.fullscreenElement will point to the element that
|
|
// is in fullscreen mode if there is one. If there isn't one,
|
|
// the value of the property is null.
|
|
if (document.fullscreenElement && document.fullscreenElement.id == iframeId) {
|
|
webView.isFullscreen = true;
|
|
window.flutter_inappwebview.nativeCommunication('onEnterFullscreen', viewId);
|
|
} else if (!document.fullscreenElement && webView.isFullscreen) {
|
|
webView.isFullscreen = false;
|
|
window.flutter_inappwebview.nativeCommunication('onExitFullscreen', viewId);
|
|
} else {
|
|
webView.isFullscreen = false;
|
|
}
|
|
});
|
|
|
|
if (iframe != null) {
|
|
webView.iframe = iframe;
|
|
webView.iframeContainer = iframeContainer;
|
|
iframe.addEventListener('load', function (event) {
|
|
webView.windowAutoincrementId = 0;
|
|
webView.windows = {};
|
|
|
|
var url = iframe.src;
|
|
try {
|
|
url = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onLoadStart', viewId, [url]);
|
|
|
|
try {
|
|
var oldLogs = {
|
|
'log': iframe.contentWindow.console.log,
|
|
'debug': iframe.contentWindow.console.debug,
|
|
'error': iframe.contentWindow.console.error,
|
|
'info': iframe.contentWindow.console.info,
|
|
'warn': iframe.contentWindow.console.warn
|
|
};
|
|
for (var k in oldLogs) {
|
|
(function(oldLog) {
|
|
iframe.contentWindow.console[oldLog] = function() {
|
|
var message = '';
|
|
for (var i in arguments) {
|
|
if (message == '') {
|
|
message += arguments[i];
|
|
} else {
|
|
message += ' ' + arguments[i];
|
|
}
|
|
}
|
|
oldLogs[oldLog].call(iframe.contentWindow.console, ...arguments);
|
|
window.flutter_inappwebview.nativeCommunication('onConsoleMessage', viewId, [oldLog, message]);
|
|
}
|
|
})(k);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
try {
|
|
var originalPushState = iframe.contentWindow.history.pushState;
|
|
iframe.contentWindow.history.pushState = function (state, unused, url) {
|
|
originalPushState.call(iframe.contentWindow.history, state, unused, url);
|
|
var iframeUrl = iframe.src;
|
|
try {
|
|
iframeUrl = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onUpdateVisitedHistory', viewId, [iframeUrl]);
|
|
};
|
|
|
|
var originalReplaceState = iframe.contentWindow.history.replaceState;
|
|
iframe.contentWindow.history.replaceState = function (state, unused, url) {
|
|
originalReplaceState.call(iframe.contentWindow.history, state, unused, url);
|
|
var iframeUrl = iframe.src;
|
|
try {
|
|
iframeUrl = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onUpdateVisitedHistory', viewId, [iframeUrl]);
|
|
};
|
|
|
|
var originalOpen = iframe.contentWindow.open;
|
|
iframe.contentWindow.open = function (url, target, windowFeatures) {
|
|
var newWindow = originalOpen.call(iframe.contentWindow, ...arguments);
|
|
var windowId = webView.windowAutoincrementId;
|
|
webView.windowAutoincrementId++;
|
|
webView.windows[windowId] = newWindow;
|
|
window.flutter_inappwebview.nativeCommunication('onCreateWindow', viewId, [windowId, url, target, windowFeatures]).then(function(){}, function(handledByClient) {
|
|
if (handledByClient) {
|
|
newWindow.close();
|
|
}
|
|
});
|
|
return newWindow;
|
|
};
|
|
|
|
var originalPrint = iframe.contentWindow.print;
|
|
iframe.contentWindow.print = function() {
|
|
var iframeUrl = iframe.src;
|
|
try {
|
|
iframeUrl = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onPrintRequest', viewId, [iframeUrl]);
|
|
originalPrint.call(iframe.contentWindow);
|
|
};
|
|
|
|
webView.functionMap = {
|
|
"window.open": iframe.contentWindow.open,
|
|
"window.print": iframe.contentWindow.print,
|
|
"window.history.pushState": iframe.contentWindow.history.pushState,
|
|
"window.history.replaceState": iframe.contentWindow.history.replaceState,
|
|
}
|
|
|
|
var initialTitle = iframe.contentDocument.title;
|
|
var titleEl = iframe.contentDocument.querySelector('title');
|
|
webView.documentTitle = initialTitle;
|
|
window.flutter_inappwebview.nativeCommunication('onTitleChanged', viewId, [initialTitle]);
|
|
if (titleEl != null) {
|
|
new MutationObserver(function(mutations) {
|
|
var title = mutations[0].target.innerText;
|
|
if (title != webView.documentTitle) {
|
|
webView.documentTitle = title;
|
|
window.flutter_inappwebview.nativeCommunication('onTitleChanged', viewId, [title]);
|
|
}
|
|
}).observe(
|
|
titleEl,
|
|
{ subtree: true, characterData: true, childList: true }
|
|
);
|
|
}
|
|
|
|
var oldPixelRatio = iframe.contentWindow.devicePixelRatio;
|
|
iframe.contentWindow.addEventListener('resize', function (e) {
|
|
var newPixelRatio = iframe.contentWindow.devicePixelRatio;
|
|
if(newPixelRatio !== oldPixelRatio){
|
|
window.flutter_inappwebview.nativeCommunication('onZoomScaleChanged', viewId, [oldPixelRatio, newPixelRatio]);
|
|
oldPixelRatio = newPixelRatio;
|
|
}
|
|
});
|
|
|
|
iframe.contentWindow.addEventListener('popstate', function (event) {
|
|
var iframeUrl = iframe.src;
|
|
try {
|
|
iframeUrl = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onUpdateVisitedHistory', viewId, [iframeUrl]);
|
|
});
|
|
|
|
iframe.contentWindow.addEventListener('scroll', function (event) {
|
|
var x = 0;
|
|
var y = 0;
|
|
try {
|
|
x = iframe.contentWindow.scrollX;
|
|
y = iframe.contentWindow.scrollY;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
window.flutter_inappwebview.nativeCommunication('onScrollChanged', viewId, [x, y]);
|
|
});
|
|
|
|
iframe.contentWindow.addEventListener('focus', function (event) {
|
|
window.flutter_inappwebview.nativeCommunication('onWindowFocus', viewId);
|
|
});
|
|
|
|
iframe.contentWindow.addEventListener('blur', function (event) {
|
|
window.flutter_inappwebview.nativeCommunication('onWindowBlur', viewId);
|
|
});
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
try {
|
|
|
|
if (!webView.settings.javaScriptCanOpenWindowsAutomatically) {
|
|
iframe.contentWindow.open = function() {
|
|
throw new Error('JavaScript cannot open windows automatically');
|
|
};
|
|
}
|
|
|
|
if (!webView.settings.verticalScrollBarEnabled && !webView.settings.horizontalScrollBarEnabled) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.verticalScrollBarEnabled-settings.horizontalScrollBarEnabled";
|
|
style.innerHTML = "body::-webkit-scrollbar { width: 0px; height: 0px; }";
|
|
iframe.contentDocument.head.append(style);
|
|
}
|
|
|
|
if (webView.settings.disableVerticalScroll) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.disableVerticalScroll";
|
|
style.innerHTML = "body { overflow-y: hidden; }";
|
|
iframe.contentDocument.head.append(style);
|
|
}
|
|
|
|
if (webView.settings.disableHorizontalScroll) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.disableHorizontalScroll";
|
|
style.innerHTML = "body { overflow-x: hidden; }";
|
|
iframe.contentDocument.head.append(style);
|
|
}
|
|
|
|
if (webView.settings.disableContextMenu) {
|
|
iframe.contentWindow.addEventListener('contextmenu', webView.disableContextMenuHandler);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
window.flutter_inappwebview.nativeCommunication('onLoadStop', viewId, [url]);
|
|
});
|
|
}
|
|
},
|
|
setSettings: function(newSettings) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
if (webView.settings.javaScriptCanOpenWindowsAutomatically != newSettings.javaScriptCanOpenWindowsAutomatically) {
|
|
if (!newSettings.javaScriptCanOpenWindowsAutomatically) {
|
|
iframe.contentWindow.open = function() {
|
|
throw new Error('JavaScript cannot open windows automatically');
|
|
};
|
|
} else {
|
|
iframe.contentWindow.open = webView.functionMap["window.open"];
|
|
}
|
|
}
|
|
|
|
if (webView.settings.verticalScrollBarEnabled != newSettings.verticalScrollBarEnabled &&
|
|
webView.settings.horizontalScrollBarEnabled != newSettings.horizontalScrollBarEnabled) {
|
|
if (!newSettings.verticalScrollBarEnabled && !newSettings.horizontalScrollBarEnabled) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.verticalScrollBarEnabled-settings.horizontalScrollBarEnabled";
|
|
style.innerHTML = "body::-webkit-scrollbar { width: 0px; height: 0px; }";
|
|
iframe.contentDocument.head.append(style);
|
|
} else {
|
|
var styleElement = iframe.contentDocument.getElementById("settings.verticalScrollBarEnabled-settings.horizontalScrollBarEnabled");
|
|
if (styleElement) { styleElement.remove() }
|
|
}
|
|
}
|
|
|
|
if (webView.settings.disableVerticalScroll != newSettings.disableVerticalScroll) {
|
|
if (newSettings.disableVerticalScroll) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.disableVerticalScroll";
|
|
style.innerHTML = "body { overflow-y: hidden; }";
|
|
iframe.contentDocument.head.append(style);
|
|
} else {
|
|
var styleElement = iframe.contentDocument.getElementById("settings.disableVerticalScroll");
|
|
if (styleElement) { styleElement.remove() }
|
|
}
|
|
}
|
|
|
|
if (webView.settings.disableHorizontalScroll != newSettings.disableHorizontalScroll) {
|
|
if (newSettings.disableHorizontalScroll) {
|
|
var style = iframe.contentDocument.createElement('style');
|
|
style.id = "settings.disableHorizontalScroll";
|
|
style.innerHTML = "body { overflow-x: hidden; }";
|
|
iframe.contentDocument.head.append(style);
|
|
} else {
|
|
var styleElement = iframe.contentDocument.getElementById("settings.disableHorizontalScroll");
|
|
if (styleElement) { styleElement.remove() }
|
|
}
|
|
}
|
|
|
|
if (webView.settings.disableContextMenu != newSettings.disableContextMenu) {
|
|
if (newSettings.disableContextMenu) {
|
|
iframe.contentWindow.addEventListener('contextmenu', webView.disableContextMenuHandler);
|
|
} else {
|
|
iframe.contentWindow.removeEventListener('contextmenu', webView.disableContextMenuHandler);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
webView.settings = newSettings;
|
|
},
|
|
reload: function() {
|
|
var iframe = webView.iframe;
|
|
if (iframe != null && iframe.contentWindow != null) {
|
|
try {
|
|
iframe.contentWindow.location.reload();
|
|
} catch (e) {
|
|
console.log(e);
|
|
iframe.contentWindow.location.href = iframe.src;
|
|
}
|
|
}
|
|
},
|
|
goBack: function() {
|
|
var iframe = webView.iframe;
|
|
if (iframe != null) {
|
|
try {
|
|
iframe.contentWindow.history.back();
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
},
|
|
goForward: function() {
|
|
var iframe = webView.iframe;
|
|
if (iframe != null) {
|
|
try {
|
|
iframe.contentWindow.history.forward();
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
},
|
|
goBackOrForward: function(steps) {
|
|
var iframe = webView.iframe;
|
|
if (iframe != null) {
|
|
try {
|
|
iframe.contentWindow.history.go(steps);
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
},
|
|
evaluateJavascript: function(source) {
|
|
var iframe = webView.iframe;
|
|
var result = null;
|
|
if (iframe != null) {
|
|
try {
|
|
result = JSON.stringify(iframe.contentWindow.eval(source));
|
|
} catch (e) {}
|
|
}
|
|
return result;
|
|
},
|
|
stopLoading: function(steps) {
|
|
var iframe = webView.iframe;
|
|
if (iframe != null) {
|
|
try {
|
|
iframe.contentWindow.stop();
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
},
|
|
getUrl: function() {
|
|
var iframe = webView.iframe;
|
|
var url = iframe.src;
|
|
try {
|
|
url = iframe.contentWindow.location.href;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return url;
|
|
},
|
|
getTitle: function() {
|
|
var iframe = webView.iframe;
|
|
var title = null;
|
|
try {
|
|
title = iframe.contentDocument.title;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return title;
|
|
},
|
|
injectJavascriptFileFromUrl: function(urlFile, scriptHtmlTagAttributes) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
var d = iframe.contentDocument;
|
|
var script = d.createElement('script');
|
|
for (var key of Object.keys(scriptHtmlTagAttributes)) {
|
|
if (scriptHtmlTagAttributes[key] != null) {
|
|
script[key] = scriptHtmlTagAttributes[key];
|
|
}
|
|
}
|
|
if (script.id != null) {
|
|
script.onload = function() {
|
|
window.flutter_inappwebview.nativeCommunication('onInjectedScriptLoaded', webView.viewId, [script.id]);
|
|
}
|
|
script.onerror = function() {
|
|
window.flutter_inappwebview.nativeCommunication('onInjectedScriptError', webView.viewId, [script.id]);
|
|
}
|
|
}
|
|
script.src = urlFile;
|
|
if (d.body != null) {
|
|
d.body.appendChild(script);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
injectCSSCode: function(source) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
var d = iframe.contentDocument;
|
|
var style = d.createElement('style');
|
|
style.innerHTML = source;
|
|
if (d.head != null) {
|
|
d.head.appendChild(style);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
injectCSSFileFromUrl: function(urlFile, cssLinkHtmlTagAttributes) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
var d = iframe.contentDocument;
|
|
var link = d.createElement('link');
|
|
for (var key of Object.keys(cssLinkHtmlTagAttributes)) {
|
|
if (cssLinkHtmlTagAttributes[key] != null) {
|
|
link[key] = cssLinkHtmlTagAttributes[key];
|
|
}
|
|
}
|
|
link.type = 'text/css';
|
|
var alternateStylesheet = "";
|
|
if (cssLinkHtmlTagAttributes.alternateStylesheet) {
|
|
alternateStylesheet = "alternate ";
|
|
}
|
|
link.rel = alternateStylesheet + "stylesheet";
|
|
link.href = urlFile;
|
|
if (d.head != null) {
|
|
d.head.appendChild(link);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
scrollTo: function(x, y, animated) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
if (animated) {
|
|
iframe.contentWindow.scrollTo({top: y, left: x, behavior: 'smooth'});
|
|
} else {
|
|
iframe.contentWindow.scrollTo(x, y);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
scrollBy: function(x, y, animated) {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
if (animated) {
|
|
iframe.contentWindow.scrollBy({top: y, left: x, behavior: 'smooth'});
|
|
} else {
|
|
iframe.contentWindow.scrollBy(x, y);
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
printCurrentPage: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
iframe.contentWindow.print();
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
},
|
|
getContentHeight: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentDocument.documentElement.scrollHeight;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return null;
|
|
},
|
|
getContentWidth: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentDocument.documentElement.scrollWidth;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return null;
|
|
},
|
|
getSelectedText: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
var txt;
|
|
var w = iframe.contentWindow;
|
|
if (w.getSelection) {
|
|
txt = w.getSelection().toString();
|
|
} else if (w.document.getSelection) {
|
|
txt = w.document.getSelection().toString();
|
|
} else if (w.document.selection) {
|
|
txt = w.document.selection.createRange().text;
|
|
}
|
|
return txt;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return null;
|
|
},
|
|
getScrollX: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentWindow.scrollX;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return null;
|
|
},
|
|
getScrollY: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentWindow.scrollY;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return null;
|
|
},
|
|
isSecureContext: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentWindow.isSecureContext;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return false;
|
|
},
|
|
canScrollVertically: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentDocument.body.scrollHeight > iframe.contentWindow.innerHeight;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return false;
|
|
},
|
|
canScrollHorizontally: function() {
|
|
var iframe = webView.iframe;
|
|
try {
|
|
return iframe.contentDocument.body.scrollWidth > iframe.contentWindow.innerWidth;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
return false;
|
|
},
|
|
getSize: function() {
|
|
var iframeContainer = webView.iframeContainer;
|
|
var width = 0.0;
|
|
var height = 0.0;
|
|
if (iframeContainer.style.width != null && iframeContainer.style.width != '' && iframeContainer.style.width.indexOf('px') > 0) {
|
|
width = parseFloat(iframeContainer.style.width);
|
|
}
|
|
if (width == null || width == 0.0) {
|
|
width = iframeContainer.getBoundingClientRect().width;
|
|
}
|
|
if (iframeContainer.style.height != null && iframeContainer.style.height != '' && iframeContainer.style.height.indexOf('px') > 0) {
|
|
height = parseFloat(iframeContainer.style.height);
|
|
}
|
|
if (height == null || height == 0.0) {
|
|
height = iframeContainer.getBoundingClientRect().height;
|
|
}
|
|
|
|
return {
|
|
width: width,
|
|
height: height
|
|
};
|
|
}
|
|
};
|
|
|
|
return webView;
|
|
},
|
|
getCookieExpirationDate: function(timestamp) {
|
|
return (new Date(timestamp)).toUTCString();
|
|
}
|
|
}; |