From 57764f171c9385c9cc2bd02e7a404c336c7c5cc2 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 22 Oct 2019 15:21:18 -0700 Subject: [PATCH 1/3] render in app webview on cp --- src/control/content/app.js | 276 ++++++++++++++++++++----------------- src/widget/widget.js | 4 +- 2 files changed, 156 insertions(+), 124 deletions(-) diff --git a/src/control/content/app.js b/src/control/content/app.js index 911ce04..ebb982a 100644 --- a/src/control/content/app.js +++ b/src/control/content/app.js @@ -1,137 +1,167 @@ -var webviewPluginApp = angular.module('webviewPlugin', []); - -webviewPluginApp.controller("webviewPluginCtrl", ["$scope", "$log", "$timeout", function ($scope, $log, $timeout) { - var dataChanged = false; - $scope.datastoreInitialized = false; - $scope.urlValid = false; - $scope.urlInValid = false; - $scope.viewType = { - NATIVE_IN_APP: 'Native In App', - IN_APP_POPUP: 'In app popup', - EXTERNAL_BROWSER: 'External browser' - }; - /* - * Go pull any previously saved data - * */ - buildfire.datastore.get(function (err, result) { - if (!err) { - $scope.datastoreInitialized = true; - } else { - console.error("Error: ", err); - return; - } - if (result && result.data && !angular.equals({}, result.data) && result.id) { - $scope.data = result.data; - $scope.id = result.id; - if (typeof result.data.content.openInApp != 'undefined' && typeof result.data.content.openInApp != 'object') { - if (result.data.content.openInApp) - $scope.data.content.view = $scope.viewType.NATIVE_IN_APP; - else - $scope.data.content.view = $scope.viewType.IN_APP_POPUP; - } - } else { - $scope.data = { - content: { - url: "", - view: $scope.viewType.NATIVE_IN_APP - } - }; - } - - /* - * watch for changes in data - * */ - $scope.$watch('data', function (newObj, oldObj) { - if (angular.equals(newObj, oldObj) || newObj == undefined) { - dataChanged = false; - } else { - dataChanged = true; - } - }, true); - - if (!$scope.$$phase && !$scope.$root.$$phase) { - $scope.$apply(); - } - }); - - $scope.saveData = function () { - if (!$scope.datastoreInitialized) { - console.error("Error with datastore didn't get called"); - return; - } - if (!dataChanged) { - console.warn("data didn't changed"); - return; - } - var data = $scope.data; - // if the form has some invalid data do not save, in our case the user eneter invalid URL - if ($scope.frmMain.$invalid) { - $log.warn('invalid data, details will not be saved'); - $scope.urlValid = false; - $scope.urlInValid = true; - $timeout(function () { - $scope.urlInValid = false; - }, 3000); - } else { - $scope.urlValid = true; - $scope.urlInValid = false; - $timeout(function () { - $scope.urlValid = false; - }, 3000); - dataChanged = false; - if (!/^https?\:\/\//.test(data.content.url)) { - data.content.url = "http://" + data.content.url; +(function(angular, buildfire) { + var webviewPluginApp = angular.module('webviewPlugin', []); + + webviewPluginApp.controller('webviewPluginCtrl', ['$scope', '$log', '$timeout', controller]); + + function controller($scope, $log, $timeout) { + var dataChanged = false; + $scope.datastoreInitialized = false; + $scope.urlValid = false; + $scope.urlInValid = false; + $scope.viewType = { + NATIVE_IN_APP: 'Native In App', + IN_APP_POPUP: 'In app popup', + EXTERNAL_BROWSER: 'External browser' + }; + + buildfire.datastore.get(function(err, result) { + if (err) return console.error('Error: ', err); + + $scope.datastoreInitialized = true; + + if (isValidResult(result)) { + $scope.data = result.data; + $scope.id = result.id; + + var type = typeof result.data.content.openInApp; + + if (type != 'undefined' && type != 'object') { + if (result.data.content.openInApp) { + $scope.data.content.view = $scope.viewType.NATIVE_IN_APP; + } else { + $scope.data.content.view = $scope.viewType.IN_APP_POPUP; + } + } + } else { + $scope.data = { + content: { + url: '', + view: $scope.viewType.NATIVE_IN_APP + } + }; + localStorage.removeItem('webview_modal-shown'); + } + + $scope.$watch('data', watchFn, true); + function watchFn(newObj, oldObj) { + if (angular.equals(newObj, oldObj) || newObj == undefined) { + dataChanged = false; + } else { + dataChanged = true; + } } - if (data.content.openInApp != undefined) - data.content.openInApp = null; - buildfire.datastore.save(data, function (err, result) { - if (err || !result) { - $log.error('Error saving the widget details: ', err); - } - else { - $log.info('Widget details saved'); - } - }); - } - }; + if (!$scope.$$phase && !$scope.$root.$$phase) { + $scope.$apply(); + } + + function isValidResult(res) { + return res && res.data && !angular.equals({}, res.data) && res.id; + } + }); + + $scope.saveData = function() { + if (!$scope.datastoreInitialized) { + return console.error("Error with datastore didn't get called"); + } - $scope.validateUrl = function () { - $scope.saveData(); - }; + if (!dataChanged) { + return console.warn("data didn't change"); + } + + if ($scope.frmMain.$invalid) return setDataInvalid(); + + var data = $scope.data; + dataChanged = false; + + setDataValid(); + showPopup(data.content); + + if (!/^https?\:\/\//.test(data.content.url)) { + data.content.url = 'http://' + data.content.url; + } + + if (data.content.openInApp != undefined) { + data.content.openInApp = null; + } + + buildfire.datastore.save(data, function(err, result) { + if (err || !result) { + return $log.error('Error saving the widget details: ', err); + } + + $log.info('Widget details saved'); + }); + + function showPopup(content) { + if (!content.view === $scope.viewType.NATIVE_IN_APP) return; + + if (localStorage.getItem('webview_modal-shown')) return; + + var options = { + title: 'In App Webview Warning', + message: 'This view may vary based on device resolution' + }; + + buildfire.notifications.showDialog(options, function() { + localStorage.setItem('webview_modal-shown', '1'); + }); + } + + function setDataInvalid() { + $log.warn('invalid data, details will not be saved'); + $scope.urlValid = false; + $scope.urlInValid = true; + $timeout(function() { + $scope.urlInValid = false; + }, 3000); + } + + function setDataValid() { + $scope.urlValid = true; + $scope.urlInValid = false; + $timeout(function() { + $scope.urlValid = false; + }, 3000); + } + }; + + $scope.validateUrl = function() { + $scope.saveData(); + }; + + $scope.changeViewType = function() { + dataChanged = true; + + if ($scope.frmMain.$invalid) return; - $scope.changeViewType = function () { - dataChanged = true; - if (!$scope.frmMain.$invalid) { var data = $scope.data; - console.log("***********save", data.content.openInApp); + if (data.content.openInApp != undefined) { data.content.openInApp = null; } - buildfire.datastore.save(data, function (err, result) { + buildfire.datastore.save(data, function(err, result) { if (err || !result) { $log.error('Error saving the widget details: ', err); - } - else { + } else { $log.info('Widget details saved'); } }); - } - }; - - $scope.openMethodChanged = function () { - dataChanged = true; - buildfire.datastore.save($scope.data, function (err, result) { - if (err || !result) { - $log.error('Error saving the widget details: ', err); - } - else { - $log.info('Widget details saved'); - } - }); - }; + }; + + $scope.openMethodChanged = function() { + dataChanged = true; + buildfire.datastore.save($scope.data, function(err, result) { + if (err || !result) { + $log.error('Error saving the widget details: ', err); + } else { + $log.info('Widget details saved'); + } + }); + }; - $scope.isUrlValid = function (url) { - return /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,6}\b(\/[-a-zA-Z0-9@:%_\+.~#?!?\/?\w\/?&//=]*)?/.test(url); - }; -}]); \ No newline at end of file + $scope.isUrlValid = function(url) { + return /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,6}\b(\/[-a-zA-Z0-9@:%_\+.~#?!?\/?\w\/?&//=]*)?/.test(url); + }; + } +})(window.angular, window.buildfire); diff --git a/src/widget/widget.js b/src/widget/widget.js index 9eccd08..e255531 100644 --- a/src/widget/widget.js +++ b/src/widget/widget.js @@ -42,8 +42,10 @@ const render = (content) => { } }; + window.document.getElementById('successMessage').style.display = 'none'; + setFlags(content); - const displayIniFrame = flags.isNotCP && flags.shouldOpenInApp; //on the device and open native + const displayIniFrame = flags.shouldOpenInApp; //on the device and open native const openWindow = flags.isNotCP && !flags.shouldOpenInApp; //on the device and open in pop up or native brow const displaySuccessMessage = content.url && flags.isWeb && !flags.isLiveMode; From 623707e35927cce6ea65d07222ec2c6fec267ac3 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 30 Oct 2019 14:59:29 -0700 Subject: [PATCH 2/3] Move warnings to control. Add warning for mixed content. Handle PWAs. --- src/control/content/app.js | 19 ++---------- src/widget/index.html | 16 ++++++++++ src/widget/widget.js | 62 +++++++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/control/content/app.js b/src/control/content/app.js index ebb982a..61bed1e 100644 --- a/src/control/content/app.js +++ b/src/control/content/app.js @@ -59,6 +59,9 @@ return res && res.data && !angular.equals({}, res.data) && res.id; } }); + buildfire.messaging.onReceivedMessage = function (message) { + buildfire.messaging.sendMessageToWidget(message); + }; $scope.saveData = function() { if (!$scope.datastoreInitialized) { @@ -75,7 +78,6 @@ dataChanged = false; setDataValid(); - showPopup(data.content); if (!/^https?\:\/\//.test(data.content.url)) { data.content.url = 'http://' + data.content.url; @@ -93,21 +95,6 @@ $log.info('Widget details saved'); }); - function showPopup(content) { - if (!content.view === $scope.viewType.NATIVE_IN_APP) return; - - if (localStorage.getItem('webview_modal-shown')) return; - - var options = { - title: 'In App Webview Warning', - message: 'This view may vary based on device resolution' - }; - - buildfire.notifications.showDialog(options, function() { - localStorage.setItem('webview_modal-shown', '1'); - }); - } - function setDataInvalid() { $log.warn('invalid data, details will not be saved'); $scope.urlValid = false; diff --git a/src/widget/index.html b/src/widget/index.html index 88a5efa..ecadf52 100755 --- a/src/widget/index.html +++ b/src/widget/index.html @@ -3,6 +3,7 @@ + @@ -21,5 +34,8 @@

Success!

web page now click here

+
+
+
diff --git a/src/widget/widget.js b/src/widget/widget.js index e255531..04c3400 100644 --- a/src/widget/widget.js +++ b/src/widget/widget.js @@ -68,6 +68,8 @@ const renderiFrame = (props) =>{ currentIframe.remove(); } + removeLoadingText(); + let scrollable = window.document.getElementById('scrollable'); if (!scrollable && props.isIOS) { window.document.body.appendChild((() => { @@ -99,6 +101,22 @@ const renderiFrame = (props) =>{ let container = props.isIOS ? scrollable : window.document.body; container.appendChild((() => { + + if (flags.isWeb) { + let modal = (document.querySelectorAll('div[id^="confirm"]') || [])[0]; + if (modal) { + let confirm = (modal.querySelectorAll('.approve-confirmation') || [])[0]; + if (confirm && confirm.click) confirm.click(); + } + + const targetProtocol = (/[a-z]{4,5}:/g.exec(props.url) || [])[0] || false; + let url = (/(http|https):\/\/\S+\.[a-z]+/g.exec(props.url) || [])[0] || 'this site'; + + if (window.location.protocol === 'https:' && targetProtocol === 'http:') { + buildfire.messaging.sendMessageToControl({ tag: 'mixedContent', url: url }); + } + } + let iFrame = window.document.createElement('iframe'); iFrame.id = 'webviewIframe'; iFrame.src = props.url; @@ -107,8 +125,13 @@ const renderiFrame = (props) =>{ iFrame.style.width = '1px'; iFrame.style.minWidth = '100%'; iFrame.onload = () => { - window.document.getElementById('loadingText').remove(); + removeLoadingText(); + buildfire.messaging.sendMessageToControl({ tag: 'displayWarning' }); }; + setTimeout(() => { + removeLoadingText(); + }, 3000); + return iFrame; })()); }; @@ -139,3 +162,40 @@ buildfire.datastore.get((err, result) => { console.log('appearance.ready() failed. Is sdk up to date?'); } }); +buildfire.messaging.onReceivedMessage = message => { + if (message.tag === 'mixedContent' && message.url) { + return mixedContentWarning(message.url); + } + if (message.tag === 'displayWarning') { + return showPopup(); + } +}; + +function removeLoadingText() { + let loadingText = window.document.getElementById('loadingText'); + if (loadingText) loadingText.remove(); +} + +function showPopup() { + if (localStorage.getItem('webview_modal-shown')) return; + + var options = { + message: 'This view may vary based on device resolution', + target: document.getElementById('warning-message'), + buttonLabels: ['I understand'] + }; + + buildfire.notifications.confirm(options, function() { + localStorage.setItem('webview_modal-shown', '1'); + }); +} + +function mixedContentWarning(url) { + var options = { + message: `Can't render ${url}. Insecure resources (http) cannot be displayed in the control panel or PWAs, but may function on devices. Some operating systems also require https.`, + target: document.getElementById('warning-message'), + buttonLabels: ['I understand'] + }; + + buildfire.notifications.confirm(options, () => { }); +} From ee5ee36e172cff16229f2575385ce01ef5642c0c Mon Sep 17 00:00:00 2001 From: Christopher Berger Date: Thu, 31 Oct 2019 16:12:49 -0700 Subject: [PATCH 3/3] remove useless localstorage call --- src/control/content/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/content/app.js b/src/control/content/app.js index 61bed1e..a6aba78 100644 --- a/src/control/content/app.js +++ b/src/control/content/app.js @@ -39,7 +39,6 @@ view: $scope.viewType.NATIVE_IN_APP } }; - localStorage.removeItem('webview_modal-shown'); } $scope.$watch('data', watchFn, true); @@ -59,6 +58,7 @@ return res && res.data && !angular.equals({}, res.data) && res.id; } }); + buildfire.messaging.onReceivedMessage = function (message) { buildfire.messaging.sendMessageToWidget(message); };