Skip to content

Instantly share code, notes, and snippets.

@kylewm
Last active August 29, 2015 14:07
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 kylewm/9d97c456011868532271 to your computer and use it in GitHub Desktop.
Save kylewm/9d97c456011868532271 to your computer and use it in GitHub Desktop.
Loads indie-config and if available, apply handlers to <indie-action> tags
// 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: {
}
});
@kylewm
Copy link
Author

kylewm commented Oct 1, 2014

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment