Skip to content

Instantly share code, notes, and snippets.

@duncanbeevers
Created May 14, 2009 21:59
Show Gist options
  • Save duncanbeevers/111954 to your computer and use it in GitHub Desktop.
Save duncanbeevers/111954 to your computer and use it in GitHub Desktop.
Prototype.CrossFrame = function() {
// Common functionality
var url_src_matcher = /^(https?:\/\/.+)\??.*/,
url_name_matcher = /\W/g,
urlForLocation = function(l) { return l.match(url_src_matcher)[1]; },
nameForUrl = function(url) { return url.replace(url_name_matcher, '-'); };
// Parent-specific closure locals
var url_map = {}, sentinel_created = false,
createSentinel = function(url) {
var name = nameForUrl(url);
$$('body')[0].insert(
new Element('iframe', {
id: name,
name: name,
style: 'width:0px;height:0px;border:0px',
src: url + '#' })
);
sentinel_created = true;
};
// Child-specific closure locals
// busy child!
var callbacks, last_sentinel_values,
sentinel_polling = false,
sentinelName = function() {
var sentinel_name;
return function() {
if (!sentinel_name) { sentinel_name = nameForUrl(urlForLocation(window.location.href)); }
return sentinel_name;
};
}(),
beginPollingSentinel = function(frequency) {
frequency |= 1000;
last_sentinel_values = {};
var poll = function() {
window.parent.frames[1];
try {
$H(window.parent.frames[sentinelName()].location.hash.slice(1).parseQuery()).each(function(t) {
if (last_sentinel_values[t.key] != t.value) {
if (callbacks[t.key]) { callbacks[t.key].each(function(callback) { callback(t.value); }); }
last_sentinel_values[t.key] = t.value;
}
});
} catch(_) {}
};
setInterval(poll, frequency);
sentinel_polling = true;
};
// Public interfaces
return {
// Parent frame functions
Parent: {
updateSentinel: function(frame_name, name, value) {
var frame = $(frame_name),
url = urlForLocation(frame.getAttribute('src')),
sentinel_name = nameForUrl(url);
if (!sentinel_created) { createSentinel(url); }
if (!url_map[url]) { url_map[url] = {}; }
url_map[url][name] = value;
(function() {
window.frames[sentinel_name].location = url + '#' + $H(url_map[url]).toQueryString();
}).defer();
}
},
// Child frame functions
Child: {
observeSentinelValue: function(name, callback) {
if (!callbacks) { callbacks = {}; }
if (!callbacks[name]) { callbacks[name] = []; }
callbacks[name].push(callback);
// if (!sentinel_created) { createSentinel(); }
if (!sentinel_polling) { beginPollingSentinel(); }
}
}
};
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment