Skip to content

Instantly share code, notes, and snippets.

@oleics
Last active December 17, 2015 14:49
Show Gist options
  • Save oleics/5627526 to your computer and use it in GitHub Desktop.
Save oleics/5627526 to your computer and use it in GitHub Desktop.
.postMessage
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<!-- Simulate a dynamically changing page -->
<div id="main"></div>
<script>
var el = document.getElementById('main');
function fill() {
while(el.childNodes.length) {
el.removeChild(el.firstChild);
}
var max = Math.round(Math.random() * 20);
for(var i=0; i<max; i++) {
var subel = document.createElement('div');
subel.appendChild(document.createTextNode('Nr. ' + i + ': ' + (+(new Date()))));
el.appendChild(subel);
}
setTimeout(fill, 1000);
}
fill();
</script>
<!-- Detect changes of the DOM -->
<script src="dom-change.js"></script>
<!-- Com with other frames -->
<script src="post-message.js"></script>
<!-- Combine both -->
<script>
var body = document.body,
iFrameMessenger = IFrameMessenger(window.parent, null, {});
listenToDOMChange(document, function() {
iFrameMessenger.run('resize', [
getDocWidth(document),
getDocHeight(document)
]);
});
function getDocWidth(d) {
return Math.max(
d.documentElement.clientWidth,
d.documentElement.scrollWidth,
d.documentElement.offsetWidth,
d.body.scrollWidth,
d.body.offsetWidth
);
}
function getDocHeight(d) {
return Math.max(
d.documentElement.clientHeight,
d.documentElement.scrollHeight,
d.documentElement.offsetHeight,
d.body.scrollHeight,
d.body.offsetHeight
);
}
</script>
</body>
</html>
var listenToDOMChange = (function() {
function bindEvent(object, event, fn) {
if(object.addEventListener) object.addEventListener(event, fn, false);
else object.attachEvent('on'+event.toLowerCase(), fn);
}
function listenToDOMChange(document, cb) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
if(MutationObserver) { // DOM4 (Chrome, Firefox)
// console.log('using MutationObserver');
var observer = new MutationObserver(function(mutations) {
onDOMChange();
});
observer.observe(document, {
subtree: true,
childList: true,
attributes: true,
characterData: true
});
} else if(isDOMSubtreeModifiedSupported(document)) { // IE9, older Firefox
// console.log('using DOMSubtreeModified');
bindEvent(document, 'DOMSubtreeModified', onDOMChange);
} else if(isDOMNodeInsertedSupported(document)) { // Opera
// console.log('using DOMNodeInserted / DOMNodeRemoved');
bindEvent(document, 'DOMNodeInserted', onDOMChange);
bindEvent(document, 'DOMNodeRemoved', onDOMChange);
} else if('onpropertychange' in document.body) { // IE
// console.log('using propertychange');
bindEvent(document, 'PropertyChange', onDOMChange);
} else {
// console.log('can not detect changes of the DOM');
}
function onDOMChange() {
cb(document);
}
}
function isDOMSubtreeModifiedSupported(document) {
var p = document.createElement('p'), flag = false;
bindEvent(p, 'DOMSubtreeModified', function() { flag = true; });
p.setAttribute('id', 'target');
return flag;
}
function isDOMNodeInsertedSupported(document) {
var p = document.createElement('p'), flag = false;
bindEvent(p, 'DOMNodeInserted', function() { flag = true; });
p.appendChild(document.createElement('p'));
return flag;
}
return listenToDOMChange;
}).call(this);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<!-- Com with other frames -->
<script src="post-message.js"></script>
<script>
var iFrame = document.createElement('iframe');
iFrame.onload = onIFrameLoad;
iFrame.src = 'http://' + location.hostname + ':3210/child.html';
document.body.appendChild(iFrame);
function onIFrameLoad() {
var iFrameMessenger = IFrameMessenger(iFrame.contentWindow, IFrameMessenger.getOriginByUrl(iFrame.src), {
resize: function(width, height) {
console.log('resize', width, height);
iFrame.width = width + 'px';
iFrame.height = height + 'px';
}
});
iFrameMessenger.run('origin', [IFrameMessenger.getOriginByUrl(window.location.href)]);
}
</script>
</body>
</html>
var IFrameMessenger = (function() {
var CODE_UNKNOWN_COMMAND = 1;
function getOriginByUrl(url) {
var a = document.createElement('a');
a.href = url;
return a.protocol + '//' + a.host;
}
var exports = function(win, origin, commands) {
commands.origin = function(newOrigin) {
console.log('origin', origin);
console.log('newOrigin', newOrigin);
origin = newOrigin;
};
// Receive
function onMessage(event) {
if(event.source === win/* && event.origin === origin*/) {
var data = JSON.parse(event.data);
if(data.command != null) {
if(commands[data.command] != null) {
var res = commands[data.command].apply(commands, data.args || []);
if(res != null) event.source.postMessage(JSON.stringify(res), event.origin);
} else {
event.source.postMessage(JSON.stringify({error: 'Unknown command: ' + data.command, code: CODE_UNKNOWN_COMMAND}), event.origin);
}
} else {
console.log(data);
}
}
}
if(window.addEventListener) {
window.addEventListener('message', onMessage, false);
} else {
window.attachEvent('onmessage', onMessage);
}
// Send
function send(data) {
win.postMessage(JSON.stringify(data), origin);
}
// Run
function run(commandName, args) {
if(args == null) args = [];
send({
command: commandName,
args: args
});
}
return {
getOriginByUrl: getOriginByUrl,
send: send,
run: run
};
};
exports.getOriginByUrl = getOriginByUrl;
return exports;
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment