Skip to content

Instantly share code, notes, and snippets.

@dhigginbotham
Last active August 29, 2015 14:24
Show Gist options
  • Save dhigginbotham/877abe896e445b656bb4 to your computer and use it in GitHub Desktop.
Save dhigginbotham/877abe896e445b656bb4 to your computer and use it in GitHub Desktop.
var murk = (function(w, d, pub, dev) {
// state reference, mostly for
// dev/internal use and context
var state = {
model: {},
dom: null,
elems: {}
};
// only way to interact with our
// model, this way we can use this
// loosely as an event emitter
function setModel(obj, str, merge) {
// we'll always set merge to true,
// this way you're not overwriting
// the model unless you intend to
merge = (typeof merge == 'undefined' ? true : false);
if (typeof str != 'undefined' && typeof obj == 'string') {
state.model[obj] = str;
// if we've set this elem before we'll
// pass that reference if possible to
// improve performance
if (state.elems.hasOwnProperty(obj)) {
return collectElems(state.elems[obj]);
}
} else {
if (Object.keys(state.model).length || merge) {
extend.call(state.model, obj);
} else {
state.model = obj;
}
}
return collectElems();
}
// gets the model, yeye
function getModel(key) {
if (typeof key != 'undefined') {
if (state.model.hasOwnProperty(key)) {
return state.model[key];
}
return null;
}
return state.model;
}
// collects elems, allows you to
// pass context so you can stay
// super snappy
function collectElems(ctx) {
if (typeof ctx != 'undefined') {
bindElem(ctx);
} else {
if (!state.dom) state.dom = d.getElementsByTagName('*');
Array.prototype.map.call(state.dom, bindElem);
}
}
// binds elem from model, simple things
function bindElem(elem) {
var attrs, key, count;
attrs = attr(elem);
key = attrs('data-murk');
if (key) {
if (state.model.hasOwnProperty(key)) {
// we only want to modify elems that
// have changed their values
if (decodeURIComponent(attrs('data-murk-val')) != state.model[key]) {
if (!state.elems.hasOwnProperty(key)) state.elems[key] = elem;
count = attrs('data-murk-count');
// encode and set a reference of our
// newly bound value
attrs('data-murk-val', encodeURIComponent(state.model[key]));
// keep visual refence we're bound
// to this elem
attrs('data-murk-bound', true);
// we want to keep track of how many
// times we're interacting with this
attrs('data-murk-count', (count ? parseInt(count,0)+1 : 1));
// finally, set innerText to our value
elem.innerText = state.model[key];
}
} else {
attrs('data-murk-bound', false);
}
}
return true;
}
// just a wrapper for elem.[set/get]Attribute()
function attr(elem) {
if (typeof elem != 'undefined') {
return function(key, val) {
if(typeof val == 'undefined') {
return this.getAttribute(key);
} else {
return this.setAttribute(key, val);
}
}.bind(elem);
} else {
return null;
}
}
// simple extend fn
function extend(obj) {
if (typeof this == 'object') {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
this[key] = obj[key];
}
}
}
}
pub.set = setModel;
if (dev) pub.state = state;
return pub;
})(window,document,{},true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment