Created
November 20, 2020 19:44
-
-
Save corlaez/a06d29606bd3ce527070932a40cc0110 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Parent Window</title> | |
<!-- Use the angular js we use at this moment --> | |
<script | |
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js" | |
integrity="sha512-CiKQCmN86Y1I8Ewkt2gGnSNmsiVrS9Ez5MoudCBhTiBJScg+GjA9OlKdaeI0IuxdCl43Fs5x5zpeew2hfOatOA==" | |
crossorigin="anonymous" | |
></script> | |
</head> | |
<body ng-app="mainApp" ng-controller="c1"> | |
<h1>Parent Window</h1> | |
<button ng-click="toggleIframe()">Toggle iFrame</button> | |
<button ng-click="toggleMessages()">Toggle Messages</button> | |
<p> | |
Send Message: | |
<button id="message_button" ng-click="sendToChild()"> | |
Hi there iframe | |
</button> | |
</p> | |
<div ng-if="showMessages"> | |
<p>Got Message:</p> | |
<p ng-repeat="m in messages">{{m.data}}</p> | |
</div> | |
<br /> | |
<angular9 ng-if="showAngular9" /> | |
<script> | |
var mainApp = angular.module("mainApp", []); | |
mainApp.controller("c1", [ | |
"$scope", | |
"$http", | |
function ($scope, $http) { | |
// view model | |
$scope.messages = []; | |
$scope.showMessages = false; | |
$scope.showAngular9 = true; | |
$scope.toggleIframe = () => { | |
$scope.showAngular9 = !$scope.showAngular9; | |
$scope.messages = []; | |
}; | |
$scope.toggleMessages = () => { | |
$scope.showMessages = !$scope.showMessages; | |
$scope.messages = []; | |
}; | |
// angular convention scope fields | |
$scope.ang9Data = "Initialization Data"; // Angular 9 props | |
$scope.ang9Loaded = (sendMessage) => { | |
console.log( | |
"Parent Controller: Angular 9 has loaded. Now button can send messages" | |
); | |
$scope.sendToChild = () => { | |
sendMessage("Click!"); | |
}; | |
}; | |
$scope.ang9Listen = (payload) => { | |
if ($scope.showMessages) { | |
$scope.messages.push({ | |
data: "Parent Controller iframe message: " + payload, | |
}); | |
} | |
}; | |
}, | |
]); | |
mainApp.directive("angular9", function () { | |
var directive = { | |
restrict: "E", // element directive | |
scope: false, // same scope as parent | |
template: | |
"<iframe src='http://localhost:4200/' id='the_iframe' style='width: 80%; height: 750px;'></iframe>", | |
}; | |
// addEventListener support for IE8 | |
function bindEvent(element, eventName, eventHandler) { | |
if (element.addEventListener) { | |
element.addEventListener(eventName, eventHandler, false); | |
} else if (element.attachEvent) { | |
element.attachEvent("on" + eventName, eventHandler); | |
} | |
} | |
const createObservable = () => { | |
let listeners = []; | |
const subscribe = (listener) => { | |
listeners.push(listener); | |
return () => { | |
listeners = listeners.filter((l) => l !== listener); | |
}; | |
}; | |
const notify = (e) => { | |
listeners.forEach((element) => { | |
element(e); | |
}); | |
}; | |
return { subscribe, notify }; | |
}; | |
//compile is called during application initialization. AngularJS calls it once when html page is loaded. | |
directive.compile = function (element, attributes) { | |
const observable = createObservable(); | |
bindEvent(window, "message", function (e) { | |
observable.notify(e); | |
}); | |
// Only executed once in the app, no unsubscribe needed. Convinient way of logging all iframes messages | |
observable.subscribe((e) => | |
console.log( | |
"Parent Logging iframe message: " + JSON.stringify(e.data) | |
) | |
); | |
//linkFunction is linked with each element with scope to get the element specific data. | |
var linkFunction = function ($scope, element, attributes) { | |
console.log("Parent: subscribe to iframe"); | |
// Make sure you are sending a string | |
var sendMessage = (msg, channel = "*") => { | |
var objMsg = null; | |
if (typeof msg !== "string" && !(msg instanceof String)) { | |
objMsg = msg; | |
} else { | |
objMsg = { type: "text", text: msg }; | |
} | |
const { contentWindow } = element[0].firstChild; | |
if (contentWindow != null) { | |
contentWindow.postMessage(objMsg, channel); | |
} | |
}; | |
var unsubscribe = observable.subscribe((e) => { | |
if (e.data.type === "init") { | |
if ($scope.ang9Loaded) $scope.ang9Loaded(sendMessage); | |
if ($scope.ang9Data) sendMessage($scope.ang9Data); | |
observable.subscribe((e) => { | |
// $apply is needed to notify ui changes in angular js correctly | |
$scope.$apply(() => $scope.ang9Listen(e.data.text)); | |
}); | |
} | |
}); | |
$scope.$on("$destroy", function () { | |
console.log("Parent: unsubscribe to iframe"); | |
unsubscribe(); | |
}); | |
}; | |
return linkFunction; | |
}; | |
return directive; | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment