Skip to content

Instantly share code, notes, and snippets.

@robshep
Last active July 16, 2021 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robshep/e935b53451765546ceca4977b475d423 to your computer and use it in GitHub Desktop.
Save robshep/e935b53451765546ceca4977b475d423 to your computer and use it in GitHub Desktop.
Changing Frame's Height By Child-to-parent browser messaging

Using Child-to-parent browser messaging to signal a frame's height based on rendered content

message listener which listens for messages from child objects to (this) parent.

handles string-encoded JSON messages with {widgetId: id, height: x} and handles changing child object height from its declared height -

handles legaacy "type-id-value" string only messages for example: "height-chart1-430" to set the height of element id="chart1" to 430px

Parent setup

HEAD section

<head>
  <script>
    (function(global){'use strict';if(!global.console){global.console={}}var con=global.console;var prop,method;var dummy=function(){};var properties=['memory'];var methods=('assert,clear,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn,timeLog,trace').split(',');while(prop=properties.pop()){if(!con[prop]){con[prop]={}}}while(method=methods.pop()){if(!con[method]){con[method]=dummy;}}})(typeof window==='undefined'?this:window);function onMessageHandler(e){if((!e.data.length)){console.log("WidgetMsg: No message");return}if(e.data[0]==="{"){console.log("WidgetMsg: Attempt JSON receiver");try{var msg=JSON.parse(e.data);if(msg.widgetId&&msg.height){var selector="[data-widget-id='"+msg.widgetId+"']";console.log("WidgetMsg: Selector",selector);var element=document.querySelector(selector);if(element){console.log("WidgetMsg: set element height",selector,msg.height);element.height=parseInt(msg.height)}else{console.log("WidgetMsg: Element not found",selector)}}}catch(error){console.log("WidgetMsg: Error",error)}}else if(e.data.indexOf("-")>0){console.log("WidgetMsg: Attempt Legacy \"type-id-value\" encoding ");var p=e.data.split("-");if(p.length!==3){console.log("WidgetMsg: Incorrect msg layout",p)}if(p[0]=="height"){var elementId=p[1];var h=parseInt(p[2]);console.log("WidgetMsg: New Frame Height",elementId,h);var el=document.getElementById(elementId);if(el){el.height=h}else{console.log("WidgetMsg: Cannot find element by ID",elementId)}}}else{console.log("WidgetMsg: Unknown Msg Encoding",e.data)}}if(window.addEventListener){window.addEventListener('message',onMessageHandler,false)}else if(window.attachEvent){window.attachEvent('onmessage',onMessageHandler)}
  </script>
</head>

content iFrame(s)

  • Markup the iframe with a unique data-widget-id="" value
  • Pass this ID into the frame src URL as a query parameter

<iframe src="http://source.of/iframe/page?widgetId=chart2" data-widget-id="chart2"></iframe>

Many iframes can be setup as long as the data-widget-id attribute has a unique value for each and they are called with their respective ID in the URL param

Child Setup

Head section

<head>
  <script>
    function parentPost(attribute,value){if(!URLSearchParams){var self=this||{};try{!function(t,e){if(new t("q=%2B").get("q")!==e||new t({q:e}).get("q")!==e||new t([["q",e]]).get("q")!==e||"q=%0A"!==new t("q=\n").toString()||"q=+%26"!==new t({q:" &"}).toString()||"q=%25zx"!==new t({q:"%zx"}).toString()){throw t}self.URLSearchParams=t}(URLSearchParams,"+")}catch(t){!function(t,a,o){"use strict";var u=t.create,h=t.defineProperty,e=/[!'\(\)~]|%20|%00/g,n=/%(?![0-9a-fA-F]{2})/g,r=/\+/g,i={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"},s={append:function(t,e){p(this._ungap,t,e)},delete:function(t){delete this._ungap[t]},get:function(t){return this.has(t)?this._ungap[t][0]:null},getAll:function(t){return this.has(t)?this._ungap[t].slice(0):[]},has:function(t){return t in this._ungap},set:function(t,e){this._ungap[t]=[a(e)]},forEach:function(e,n){var r=this;for(var i in r._ungap){r._ungap[i].forEach(t,i)}function t(t){e.call(n,t,a(i),r)}},toJSON:function(){return{}},toString:function(){var t=[];for(var e in this._ungap){for(var n=v(e),r=0,i=this._ungap[e];r<i.length;r+=1){t.push(n+"="+v(i[r]))}}return t.join("&")}};for(var c in s){h(f.prototype,c,{configurable:!0,writable:!0,value:s[c]})}function f(t){var e=u(null);switch(h(this,"_ungap",{value:e}),!0){case!t:break;case "string"==typeof t:"?"===t.charAt(0)&&(t=t.slice(1));for(var n=t.split("&"),r=0,i=n.length;r<i;r+=1){var a=(s=n[r]).indexOf("=");-1<a?p(e,g(s.slice(0,a)),g(s.slice(a+1))):s.length&&p(e,g(s),"")}break;case o(t):for(var s,r=0,i=t.length;r<i;r+=1){p(e,(s=t[r])[0],s[1])}break;case "forEach"in t:t.forEach(l,e);break;default:for(var c in t){p(e,c,t[c])}}}function l(t,e){p(this,e,t)}function p(t,e,n){var r=o(n)?n.join(","):n;e in t?t[e].push(r):t[e]=[r]}function g(t){return decodeURIComponent(t.replace(n,"%25").replace(r," "))}function v(t){return encodeURIComponent(t).replace(e,d)}function d(t){return i[t]}self.URLSearchParams=f}(Object,String,Array.isArray)}!function(d){var r=!1;try{r=!!Symbol.iterator}catch(t){}function t(t,e){var n=[];return t.forEach(e,n),r?n[Symbol.iterator]():{next:function(){var t=n.shift();return{done:void 0===t,value:t}}}}"forEach"in d||(d.forEach=function(n,r){var i=this,t=Object.create(null);this.toString().replace(/=[\s\S]*?(?:&|$)/g,"=").split("=").forEach(function(e){!e.length||e in t||(t[e]=i.getAll(e)).forEach(function(t){n.call(r,t,e,i)})})}),"keys"in d||(d.keys=function(){return t(this,function(t,e){this.push(e)})}),"values"in d||(d.values=function(){return t(this,function(t,e){this.push(t)})}),"entries"in d||(d.entries=function(){return t(this,function(t,e){this.push([e,t])})}),!r||Symbol.iterator in d||(d[Symbol.iterator]=d.entries),"sort"in d||(d.sort=function(){for(var t,e,n,r=this.entries(),i=r.next(),a=i.done,s=[],c=Object.create(null);!a;){e=(n=i.value)[0],s.push(e),e in c||(c[e]=[]),c[e].push(n[1]),a=(i=r.next()).done}for(s.sort(),t=0;t<s.length;t+=1){this.delete(s[t])}for(t=0;t<s.length;t+=1){e=s[t],this.append(e,c[e].shift())}}),function(f){function l(t){var e=t.append;t.append=d.append,URLSearchParams.call(t,t._usp.search.slice(1)),t.append=e}function p(t,e){if(!(t instanceof e)){throw new TypeError("'searchParams' accessed on an object that does not implement interface "+e.name)}}function t(e){var n,r,i,t=e.prototype,a=v(t,"searchParams"),s=v(t,"href"),c=v(t,"search");function o(t,e){d.append.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function u(t){d.delete.call(this,t),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function h(t,e){d.set.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}!a&&c&&c.set&&(i=c,r=function(t,e){return t.append=o,t.delete=u,t.set=h,g(t,"_usp",{configurable:!0,writable:!0,value:e})},n=function(t,e){return g(t,"_searchParams",{configurable:!0,writable:!0,value:r(e,t)}),e},f.defineProperties(t,{href:{get:function(){return s.get.call(this)},set:function(t){var e=this._searchParams;s.set.call(this,t),e&&l(e)}},search:{get:function(){return c.get.call(this)},set:function(t){var e=this._searchParams;c.set.call(this,t),e&&l(e)}},searchParams:{get:function(){return p(this,e),this._searchParams||n(this,new URLSearchParams(this.search.slice(1)))},set:function(t){p(this,e),n(this,t)}}}))}var g=f.defineProperty,v=f.getOwnPropertyDescriptor;try{t(HTMLAnchorElement),/^function|object$/.test(typeof URL)&&URL.prototype&&t(URL)}catch(t){}}(Object)}(self.URLSearchParams.prototype,Object)}var params=new URLSearchParams(window.location.search);var widgetId=params.get("widgetId");if(!widgetId){console.log("No Widget ID",params);return}var msg={widgetId:widgetId};msg[attribute]=value;var msgStr=JSON.stringify(msg);parent.postMessage(msgStr,"*")}
  </script>
</head>

In runtime code ...

When the content is ready (E.g. after a chart has plotted) and the content height has been established call the function

var widget_height =  document.getElementById("content").offsetHeight
parentPost("height", widget_height)
/**
* Add this code and call function when the content is ready (E.g. after a chart has plotted) and the content height has been established
* - The page this executes on needs a ?widgetId=<ID> URL parameter
* - The parent of this page will need to have the iFrame marked up with data-widget-id=<ID>
* - Use arbitary but unique IDs for all the widgets on the page
*
* Example:
* var widget_height = document.getElementById("content").offsetHeight
* parentPost("height", widget_height)
*/
function parentPost(attribute, value) {
/*! (c) Andrea Giammarchi - ISC - https://github.com/ungap/url-search-params*/
if(!URLSearchParams){ var self=this||{};try{!function(t,e){if(new t("q=%2B").get("q")!==e||new t({q:e}).get("q")!==e||new t([["q",e]]).get("q")!==e||"q=%0A"!==new t("q=\n").toString()||"q=+%26"!==new t({q:" &"}).toString()||"q=%25zx"!==new t({q:"%zx"}).toString())throw t;self.URLSearchParams=t}(URLSearchParams,"+")}catch(t){!function(t,a,o){"use strict";var u=t.create,h=t.defineProperty,e=/[!'\(\)~]|%20|%00/g,n=/%(?![0-9a-fA-F]{2})/g,r=/\+/g,i={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"},s={append:function(t,e){p(this._ungap,t,e)},delete:function(t){delete this._ungap[t]},get:function(t){return this.has(t)?this._ungap[t][0]:null},getAll:function(t){return this.has(t)?this._ungap[t].slice(0):[]},has:function(t){return t in this._ungap},set:function(t,e){this._ungap[t]=[a(e)]},forEach:function(e,n){var r=this;for(var i in r._ungap)r._ungap[i].forEach(t,i);function t(t){e.call(n,t,a(i),r)}},toJSON:function(){return{}},toString:function(){var t=[];for(var e in this._ungap)for(var n=v(e),r=0,i=this._ungap[e];r<i.length;r++)t.push(n+"="+v(i[r]));return t.join("&")}};for(var c in s)h(f.prototype,c,{configurable:!0,writable:!0,value:s[c]});function f(t){var e=u(null);switch(h(this,"_ungap",{value:e}),!0){case!t:break;case"string"==typeof t:"?"===t.charAt(0)&&(t=t.slice(1));for(var n=t.split("&"),r=0,i=n.length;r<i;r++){var a=(s=n[r]).indexOf("=");-1<a?p(e,g(s.slice(0,a)),g(s.slice(a+1))):s.length&&p(e,g(s),"")}break;case o(t):for(var s,r=0,i=t.length;r<i;r++){p(e,(s=t[r])[0],s[1])}break;case"forEach"in t:t.forEach(l,e);break;default:for(var c in t)p(e,c,t[c])}}function l(t,e){p(this,e,t)}function p(t,e,n){var r=o(n)?n.join(","):n;e in t?t[e].push(r):t[e]=[r]}function g(t){return decodeURIComponent(t.replace(n,"%25").replace(r," "))}function v(t){return encodeURIComponent(t).replace(e,d)}function d(t){return i[t]}self.URLSearchParams=f}(Object,String,Array.isArray)}!function(d){var r=!1;try{r=!!Symbol.iterator}catch(t){}function t(t,e){var n=[];return t.forEach(e,n),r?n[Symbol.iterator]():{next:function(){var t=n.shift();return{done:void 0===t,value:t}}}}"forEach"in d||(d.forEach=function(n,r){var i=this,t=Object.create(null);this.toString().replace(/=[\s\S]*?(?:&|$)/g,"=").split("=").forEach(function(e){!e.length||e in t||(t[e]=i.getAll(e)).forEach(function(t){n.call(r,t,e,i)})})}),"keys"in d||(d.keys=function(){return t(this,function(t,e){this.push(e)})}),"values"in d||(d.values=function(){return t(this,function(t,e){this.push(t)})}),"entries"in d||(d.entries=function(){return t(this,function(t,e){this.push([e,t])})}),!r||Symbol.iterator in d||(d[Symbol.iterator]=d.entries),"sort"in d||(d.sort=function(){for(var t,e,n,r=this.entries(),i=r.next(),a=i.done,s=[],c=Object.create(null);!a;)e=(n=i.value)[0],s.push(e),e in c||(c[e]=[]),c[e].push(n[1]),a=(i=r.next()).done;for(s.sort(),t=0;t<s.length;t++)this.delete(s[t]);for(t=0;t<s.length;t++)e=s[t],this.append(e,c[e].shift())}),function(f){function l(t){var e=t.append;t.append=d.append,URLSearchParams.call(t,t._usp.search.slice(1)),t.append=e}function p(t,e){if(!(t instanceof e))throw new TypeError("'searchParams' accessed on an object that does not implement interface "+e.name)}function t(e){var n,r,i,t=e.prototype,a=v(t,"searchParams"),s=v(t,"href"),c=v(t,"search");function o(t,e){d.append.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function u(t){d.delete.call(this,t),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function h(t,e){d.set.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}!a&&c&&c.set&&(i=c,r=function(t,e){return t.append=o,t.delete=u,t.set=h,g(t,"_usp",{configurable:!0,writable:!0,value:e})},n=function(t,e){return g(t,"_searchParams",{configurable:!0,writable:!0,value:r(e,t)}),e},f.defineProperties(t,{href:{get:function(){return s.get.call(this)},set:function(t){var e=this._searchParams;s.set.call(this,t),e&&l(e)}},search:{get:function(){return c.get.call(this)},set:function(t){var e=this._searchParams;c.set.call(this,t),e&&l(e)}},searchParams:{get:function(){return p(this,e),this._searchParams||n(this,new URLSearchParams(this.search.slice(1)))},set:function(t){p(this,e),n(this,t)}}}))}var g=f.defineProperty,v=f.getOwnPropertyDescriptor;try{t(HTMLAnchorElement),/^function|object$/.test(typeof URL)&&URL.prototype&&t(URL)}catch(t){}}(Object)}(self.URLSearchParams.prototype,Object); }
var params = new URLSearchParams(window.location.search);
var widgetId = params.get("widgetId")
if(!widgetId){ console.log("No Widget ID", params); return }
var msg = { widgetId: widgetId }
msg[attribute] = value
var msgStr = JSON.stringify(msg)
parent.postMessage(msgStr, "*" )
}
<!DOCTYPE html>
<html>
<head>
<title>iFrame resize test</title>
<script>
function parentPost(attribute,value){if(!URLSearchParams){var self=this||{};try{!function(t,e){if(new t("q=%2B").get("q")!==e||new t({q:e}).get("q")!==e||new t([["q",e]]).get("q")!==e||"q=%0A"!==new t("q=\n").toString()||"q=+%26"!==new t({q:" &"}).toString()||"q=%25zx"!==new t({q:"%zx"}).toString()){throw t}self.URLSearchParams=t}(URLSearchParams,"+")}catch(t){!function(t,a,o){"use strict";var u=t.create,h=t.defineProperty,e=/[!'\(\)~]|%20|%00/g,n=/%(?![0-9a-fA-F]{2})/g,r=/\+/g,i={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"},s={append:function(t,e){p(this._ungap,t,e)},delete:function(t){delete this._ungap[t]},get:function(t){return this.has(t)?this._ungap[t][0]:null},getAll:function(t){return this.has(t)?this._ungap[t].slice(0):[]},has:function(t){return t in this._ungap},set:function(t,e){this._ungap[t]=[a(e)]},forEach:function(e,n){var r=this;for(var i in r._ungap){r._ungap[i].forEach(t,i)}function t(t){e.call(n,t,a(i),r)}},toJSON:function(){return{}},toString:function(){var t=[];for(var e in this._ungap){for(var n=v(e),r=0,i=this._ungap[e];r<i.length;r+=1){t.push(n+"="+v(i[r]))}}return t.join("&")}};for(var c in s){h(f.prototype,c,{configurable:!0,writable:!0,value:s[c]})}function f(t){var e=u(null);switch(h(this,"_ungap",{value:e}),!0){case!t:break;case "string"==typeof t:"?"===t.charAt(0)&&(t=t.slice(1));for(var n=t.split("&"),r=0,i=n.length;r<i;r+=1){var a=(s=n[r]).indexOf("=");-1<a?p(e,g(s.slice(0,a)),g(s.slice(a+1))):s.length&&p(e,g(s),"")}break;case o(t):for(var s,r=0,i=t.length;r<i;r+=1){p(e,(s=t[r])[0],s[1])}break;case "forEach"in t:t.forEach(l,e);break;default:for(var c in t){p(e,c,t[c])}}}function l(t,e){p(this,e,t)}function p(t,e,n){var r=o(n)?n.join(","):n;e in t?t[e].push(r):t[e]=[r]}function g(t){return decodeURIComponent(t.replace(n,"%25").replace(r," "))}function v(t){return encodeURIComponent(t).replace(e,d)}function d(t){return i[t]}self.URLSearchParams=f}(Object,String,Array.isArray)}!function(d){var r=!1;try{r=!!Symbol.iterator}catch(t){}function t(t,e){var n=[];return t.forEach(e,n),r?n[Symbol.iterator]():{next:function(){var t=n.shift();return{done:void 0===t,value:t}}}}"forEach"in d||(d.forEach=function(n,r){var i=this,t=Object.create(null);this.toString().replace(/=[\s\S]*?(?:&|$)/g,"=").split("=").forEach(function(e){!e.length||e in t||(t[e]=i.getAll(e)).forEach(function(t){n.call(r,t,e,i)})})}),"keys"in d||(d.keys=function(){return t(this,function(t,e){this.push(e)})}),"values"in d||(d.values=function(){return t(this,function(t,e){this.push(t)})}),"entries"in d||(d.entries=function(){return t(this,function(t,e){this.push([e,t])})}),!r||Symbol.iterator in d||(d[Symbol.iterator]=d.entries),"sort"in d||(d.sort=function(){for(var t,e,n,r=this.entries(),i=r.next(),a=i.done,s=[],c=Object.create(null);!a;){e=(n=i.value)[0],s.push(e),e in c||(c[e]=[]),c[e].push(n[1]),a=(i=r.next()).done}for(s.sort(),t=0;t<s.length;t+=1){this.delete(s[t])}for(t=0;t<s.length;t+=1){e=s[t],this.append(e,c[e].shift())}}),function(f){function l(t){var e=t.append;t.append=d.append,URLSearchParams.call(t,t._usp.search.slice(1)),t.append=e}function p(t,e){if(!(t instanceof e)){throw new TypeError("'searchParams' accessed on an object that does not implement interface "+e.name)}}function t(e){var n,r,i,t=e.prototype,a=v(t,"searchParams"),s=v(t,"href"),c=v(t,"search");function o(t,e){d.append.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function u(t){d.delete.call(this,t),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}function h(t,e){d.set.call(this,t,e),t=this.toString(),i.set.call(this._usp,t?"?"+t:"")}!a&&c&&c.set&&(i=c,r=function(t,e){return t.append=o,t.delete=u,t.set=h,g(t,"_usp",{configurable:!0,writable:!0,value:e})},n=function(t,e){return g(t,"_searchParams",{configurable:!0,writable:!0,value:r(e,t)}),e},f.defineProperties(t,{href:{get:function(){return s.get.call(this)},set:function(t){var e=this._searchParams;s.set.call(this,t),e&&l(e)}},search:{get:function(){return c.get.call(this)},set:function(t){var e=this._searchParams;c.set.call(this,t),e&&l(e)}},searchParams:{get:function(){return p(this,e),this._searchParams||n(this,new URLSearchParams(this.search.slice(1)))},set:function(t){p(this,e),n(this,t)}}}))}var g=f.defineProperty,v=f.getOwnPropertyDescriptor;try{t(HTMLAnchorElement),/^function|object$/.test(typeof URL)&&URL.prototype&&t(URL)}catch(t){}}(Object)}(self.URLSearchParams.prototype,Object)}var params=new URLSearchParams(window.location.search);var widgetId=params.get("widgetId");if(!widgetId){console.log("No Widget ID",params);return}var msg={widgetId:widgetId};msg[attribute]=value;var msgStr=JSON.stringify(msg);parent.postMessage(msgStr,"*")}
</script>
</head>
<body>
<div id="wrapper">
<div id="content" style="background-color: blue; width: 100%; height: 123px">&nbsp;</div>
<script>
setTimeout(function(){
document.getElementById("content").style.height = '400px';
var widget_height = document.getElementById("wrapper").offsetHeight;
parentPost("height", widget_height)
}, 3000)
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>iFrame resize test</title>
<script>
(function(global){'use strict';if(!global.console){global.console={}}var con=global.console;var prop,method;var dummy=function(){};var properties=['memory'];var methods=('assert,clear,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn,timeLog,trace').split(',');while(prop=properties.pop()){if(!con[prop]){con[prop]={}}}while(method=methods.pop()){if(!con[method]){con[method]=dummy;}}})(typeof window==='undefined'?this:window);function onMessageHandler(e){if((!e.data.length)){console.log("WidgetMsg: No message");return}if(e.data[0]==="{"){console.log("WidgetMsg: Attempt JSON receiver");try{var msg=JSON.parse(e.data);if(msg.widgetId&&msg.height){var selector="[data-widget-id='"+msg.widgetId+"']";console.log("WidgetMsg: Selector",selector);var element=document.querySelector(selector);if(element){console.log("WidgetMsg: set element height",selector,msg.height);element.height=parseInt(msg.height)}else{console.log("WidgetMsg: Element not found",selector)}}}catch(error){console.log("WidgetMsg: Error",error)}}else if(e.data.indexOf("-")>0){console.log("WidgetMsg: Attempt Legacy \"type-id-value\" encoding ");var p=e.data.split("-");if(p.length!==3){console.log("WidgetMsg: Incorrect msg layout",p)}if(p[0]=="height"){var elementId=p[1];var h=parseInt(p[2]);console.log("WidgetMsg: New Frame Height",elementId,h);var el=document.getElementById(elementId);if(el){el.height=h}else{console.log("WidgetMsg: Cannot find element by ID",elementId)}}}else{console.log("WidgetMsg: Unknown Msg Encoding",e.data)}}if(window.addEventListener){window.addEventListener('message',onMessageHandler,false)}else if(window.attachEvent){window.attachEvent('onmessage',onMessageHandler)}
</script>
</head>
<body>
<iframe src="./frame.html?widgetId=abc123" data-widget-id="abc123" frameborder="0" scrolling="no"></iframe>
</body>
</html>
/**
* This whole snippet can be included in a <script> in the head so it is ready before child frames are loaded
*/
// Console-polyfill. MIT license.
// https://github.com/paulmillr/console-polyfill
// Make it safe to do console.log() always.
(function(global) {
'use strict';
if (!global.console) {
global.console = {};
}
var con = global.console;
var prop, method;
var dummy = function() {};
var properties = ['memory'];
var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn,timeLog,trace').split(',');
while (prop = properties.pop()) if (!con[prop]) con[prop] = {};
while (method = methods.pop()) if (!con[method]) con[method] = dummy;
// Using `this` for web workers & supports Browserify / Webpack.
})(typeof window === 'undefined' ? this : window);
/*
* message listener which listens for messages from child objects to (this) parent.
*
* handles string-encoded JSON messages with {widgetId: id, height: x} and handles changing child object height from its declared height -
* - the child object is marked up as data-widget-id="{widgetId}" in the HTML element
* - this ID is passed to the child somehow, typically via iframe URL so it can take it pass it back:
* - Like this: <iframe src="http://source.of/child/page?widgetId={widgetId}" data-widget-id="{widgetId}"></iframe>
* - Example: <iframe src="http://source.of/child/page?widgetId=chart2" data-widget-id=}"></iframe>
*
* handles legaacy "type-id-value" string only messages for example: "height-chart1-430" to set the height of element id="chart1" to 430px
*
*
*/
function onMessageHandler(e) {
if( (!e.data.length) ) {
console.log("WidgetMsg: No message")
return;
}
if( e.data[0] === "{" ) {
console.log("WidgetMsg: Attempt JSON receiver")
try {
var msg = JSON.parse(e.data)
if(msg.widgetId && msg.height) {
var selector = "[data-widget-id='" + msg.widgetId + "']"
console.log("WidgetMsg: Selector", selector)
var element = document.querySelector(selector);
if(element) {
console.log("WidgetMsg: set element height", selector, msg.height)
element.height = parseInt(msg.height)
} else {
console.log("WidgetMsg: Element not found", selector)
}
}
}
catch(error){
console.log("WidgetMsg: Error", error)
}
}
else if(e.data.indexOf("-") > 0 )
{
console.log("WidgetMsg: Attempt Legacy \"type-id-value\" encoding ")
var p = e.data.split("-")
if(p.length !== 3){
console.log("WidgetMsg: Incorrect msg layout", p)
}
if (p[0] == "height") {
var elementId = p[1]
var h = parseInt(p[2])
console.log("WidgetMsg: New Frame Height", elementId, h)
var el = document.getElementById(elementId)
if(el){
el.height = h
} else {
console.log("WidgetMsg: Cannot find element by ID", elementId)
}
}
}
else {
console.log("WidgetMsg: Unknown Msg Encoding", e.data)
}
}
/*
* add message receiver
*/
if (window.addEventListener) {
window.addEventListener('message', onMessageHandler, false);
} else if (window.attachEvent) {
window.attachEvent('onmessage', onMessageHandler);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment