Last active
August 29, 2015 14:07
-
-
Save karadaisy/9d97c456011868532271 to your computer and use it in GitHub Desktop.
Loads indie-config and if available, apply handlers to <indie-action> tags
This file contains hidden or 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
// Lazy-create and return an indie-config load promise | |
// The promise will be resolved with a config once the indie-config has been loaded | |
var loadIndieConfig = function () { | |
// Create the Promise to return | |
var loadPromise = new Promise(function (resolve) { | |
// Parse the incoming messages | |
var parseIndieConfig = function (message) { | |
// Check if the message comes from the indieConfigFrame we added (or from some other frame) | |
if (message.source !== indieConfigFrame.contentWindow) { | |
return; | |
} | |
var indieConfig; | |
// Try to parse the config, it can be malformed | |
try { | |
indieConfig = JSON.parse(message.data); | |
} catch (e) {} | |
// We're done – remove the frame and event listener | |
window.removeEventListener('message', parseIndieConfig); | |
indieConfigFrame.parentNode.removeChild(indieConfigFrame); | |
indieConfigFrame = undefined; | |
// And resolve the promise with the loaded indie-config | |
resolve(indieConfig); | |
}; | |
// Listen for messages from the added iframe and parse those messages | |
window.addEventListener('message', parseIndieConfig); | |
// Create a hidden iframe pointing to something using the web+action: protocol | |
var indieConfigFrame = document.createElement('iframe'); | |
indieConfigFrame.src = 'web+action:load'; | |
document.getElementsByTagName('body')[0].appendChild(indieConfigFrame); | |
indieConfigFrame.style.display = 'none'; | |
}); | |
// Ensure that subsequent invocations return the same promise | |
loadIndieConfig = function () { | |
return loadPromise; | |
}; | |
return loadPromise; | |
}; | |
xtag.register('indie-action', { | |
lifecycle: { | |
created: function() { | |
if (!this.innerHTML) { | |
this.innerHTML = '<a href="#"></a>'; | |
} | |
first('a', this).textContent = this.getAttribute('do').substring(0, 1).toUpperCase() + this.getAttribute('do').substring(1); | |
}, | |
inserted: function() {}, | |
removed: function() {}, | |
attributeChanged: function() {} | |
}, | |
events: { | |
'click:delegate(a)': function(e) { | |
var elem = this.parentNode; | |
e.preventDefault(); | |
var d = elem.getAttribute('do'); | |
var w = elem.getAttribute('with'); | |
var href = this.href; | |
if (d && w) { | |
loadIndieConfig().then(function(indieConfig) { | |
var handler = indieConfig[d]; | |
if (handler) { | |
href = handler.replace('{url}', encodeURIComponent(w || window.location.href)); | |
} | |
window.location = href; | |
}); | |
} | |
} | |
}, | |
accessors: { | |
}, | |
methods: { | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have not quite figured out how to detect that no web+action handler is registered, and fall back to appropriate (e.g. twitter intent) urls.