Skip to content

Instantly share code, notes, and snippets.

@nbubna
Created December 22, 2014 23:43
Show Gist options
  • Save nbubna/304659d5f5c42a5152c5 to your computer and use it in GitHub Desktop.
Save nbubna/304659d5f5c42a5152c5 to your computer and use it in GitHub Desktop.
On demand, duplicate prototype chain for creating performant, polymorphic, type-aware extensions on per-instance DOM wrapper objects. (rough draft)
window.X = {};
function fnName(fn){
if (!fn){ return null; }
if (fn.name){ return fn.name; }
var s = fn.toString().match(/ \w+/);
return s && s[0].substring(1);
}
function xType(name, type) {
if (name in X) {
return X[name];
}
if (!name || !type || type === Object) {
return Object;
}
//console.debug('xType', name, type);
var xtype = new Function("return function "+name+"X(node){ this.node = node; };")();
var parentType = Object.getPrototypeOf(type),
parentName = fnName(parentType),
parentXType = xType(parentName, parentType);
//console.debug('parentXType', parentXType, parentName);
xtype.prototype = new parentXType();
return X[name] = xtype;
}
Object.defineProperty(Node.prototype, 'x', {
get: function() {
var type = this.constructor,
xtype = xType(fnName(type), type),
x = new xtype(this);
//console.log('x:get', this.tagName, fnName(type), fnName(xtype), x);
Object.defineProperty(this, 'x', {value:x});
return x;
},
configurable: true,
enumerable: false,
writeable: true
});
X.define = function(type, name, fn) {
var xtype = xType(fnName(type), type);
xtype.prototype[name] = function() {
return fn.apply(this.node, arguments);
};
};
X.define(Element, 'val', function() {
return this.textContent;
});
X.define(HTMLInputElement, 'val', function() {
return this.value;
});
/* Assuming you have an input and span element in your test page, do:
var input = document.querySelector('input'),
span = document.querySelector('span');
console.log('span.x replacement', span.x === span.x);
console.log('input.x.val()', input.x.val());
console.log('span.x.val()', span.x.val());
//*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment