Skip to content

Instantly share code, notes, and snippets.

@jsmaker
Created June 28, 2012 10:24
Show Gist options
  • Save jsmaker/3010529 to your computer and use it in GitHub Desktop.
Save jsmaker/3010529 to your computer and use it in GitHub Desktop.
some inheritance tests on view object
//Element.prototype.__appendChild = Element.prototype.appendChild;
//Element.prototype.appendChild = function(){Element.prototype.__appendChild.apply(this, arguments); this.classList.contains('view') && console.log.apply(console, arguments)};
var BObject = function BObject() {};
BObject.$super = function (fn, args, name, parent) {
parent = parent || this.parent();
debugger;
if (parent) {
if (parent.name === name && parent.prototype[fn]) {
fn = parent.prototype[fn];
return fn && fn.apply(this, args);
} else {
this.$super(fn, args,name, parent);
}
}
};
BObject.parent = function () {
return undefined;
};
BObject.childOf = function (BObjectType) {
var obj = this;
while (obj) {
if (BObjectType === obj.name) {
return true;
}
obj = obj.parent ? obj.parent() : false;
}
return false;
};
BObject.inheritancePath = function (more) {
var obj = this;
var path = [];
while (obj) {
if (more) {
path.unshift({name:obj.name, constructor:obj});
}else {
path.unshift(obj.name);
}
obj = obj.parent ? obj.parent() : false;
}
return path;
};
BObject.create = function (O1) {
console.count(O1.name || O1);
if (typeof O1 === 'string') {
O1 = (new Function('return function ' + O1 + '(){this.init(arguments);}'))();
}
BObject.create.classes[O1.name] = O1;
var O2 = this;
var parent = function (name) {
if (name) {
if (O2.name === name) {
return O2;
}
return O2.parent(name);
}
return O2;
};
O1.create = O2.create;
O1.inheritancePath = O2.inheritancePath;
O1.$super = O2.$super;
O1.guid = O2.guid;
O1.parent = parent;
O1.childOf = O2.childOf;
//O1.instance = O1.prototype;
O1.prototype = Object.create(O2.prototype);
O1.prototype.parent = parent;
O1.prototype.guid = O1.guid(O1.name);
O1.prototype.constructor = O1;
return O1;
};
BObject.create.classes = {
BObject: BObject
};
BObject.guid = function (prefix) {
var counterMap = BObject.guid.counterMap;
var add = function () {
if (counterMap[prefix] >= 0) {
counterMap[prefix] += 1;
} else {
counterMap[prefix] = 0;
}
return prefix + counterMap[prefix];
};
add.counterMap = counterMap;
return add;
};
BObject.guid.counterMap = {};
BObject.prototype.guid = BObject.guid('BObject');
BObject.prototype.initialize = function (repeatElement) {
this.id = this.guid();
this.props = {};
this.data = {};
};
BObject.prototype.runSuper = function (fn, args) {
var parent;
if ((parent = this.parent())) {
fn = parent.prototype[fn];
return fn && fn.apply(this, args);
}
};
BObject.prototype.log = function () {
var args = Array.prototype.slice.call(arguments) ;
args.unshift(this.id + ': ');
console.log.apply(console, args);
};
BObject.prototype.parent = BObject.parent;
BObject.prototype.init = function (args) {
var parents;
var parent = this.parent();
var stack = [];
while (parent) {
stack.push(parent.prototype);
parent = parent.parent ? parent.parent() : false;
}
parents = stack.pop();
while (parents) {
parents.initialize.apply(this, args);
parents = stack.pop();
}
this.initialize.apply(this, args);
return this;
};
BObject.prototype.instanceOf = function (BObjectType) {
var obj = this.constructor;
while (obj) {
if (BObjectType === obj.name) {
return true;
}
obj = obj.parent ? obj.parent() : false;
}
return false;
};
var Observer = BObject.create('Observer');
Observer.prototype.initialize = function () {
this.listeners = {};
};
Observer.prototype.set = function (propName, newVlaue, namespace) {
var self,
oldValue;
namespace = namespace || 'this';
if (namespace === 'this') {
self = this;
} else {
self = this[namespace];
if (!self) {
self = this[namespace] = {};
}
}
oldValue = self[propName];
self[propName] = newVlaue;
this.fireListeners('propChange', propName, oldValue, newVlaue);
return newVlaue;
};
Observer.prototype.addListener = function (channel, fn) {
this.listeners[channel] = this.listeners[channel] || [];
this.listeners[channel].push(fn);
};
Observer.prototype.fireListeners = function (channel, propName, oldValue, newVlaue) {
var listeners = this.listeners[channel];
if (listeners) {
for (var i = 0; i < listeners.length; i++) {
listeners[i].apply(this, arguments);
}
}
return this;
};
Observer.prototype.getFireStarter = function (channel, propName) {
var observer = this;
return function(data){
observer.fireListeners(channel, propName, data);
};
};
var View = Observer.create('View');
window.View = View;
View.createCSS = function (selector, declaration, style_node) {
var rules;
var i;
style_node = View.styleNode || style_node;
if (style_node) {
rules = style_node.sheet.rules || style_node.sheet.cssRules;
for (i = rules.length; i--; 1) {
if (rules[i].selectorText === selector) {
//style_node.sheet.deleteRule(i);
return style_node;
}
}
}
// test for IE
var ua = navigator.userAgent.toLowerCase();
var isIE = (/msie/.test(ua)) && !(/opera/.test(ua)) && (/win/.test(ua));
// create the style node for all browsers
style_node = style_node || (function () {
var style_node = document.createElement("style");
style_node.setAttribute("type", "text/css");
style_node.setAttribute("media", "screen");
return style_node;
}());
// append a rule for good browsers
if (!isIE){
style_node.appendChild(document.createTextNode(selector + " {" + declaration + "}"));
}
// append the style node
document.getElementsByTagName("head")[0].appendChild(style_node);
// use alternative methods for IE
if (isIE && document.styleSheets && document.styleSheets.length > 0) {
var last_style_node = document.styleSheets[document.styleSheets.length - 1];
if (typeof(last_style_node.addRule) === "object"){
last_style_node.addRule(selector, declaration);
}
}
return style_node;
}
View.styleNode = View.createCSS('*', '-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;');
View.createCSS('.box-view','background:#f3f3f3;margin:10px 0;width:100%;');
View.createCSS('.box-view-node','padding:1%;margin:0;display:inline-block;vertical-align:top;');
View.getAll = function(){
var viewsList = Array.prototype.map.call(document.querySelectorAll('.view'), function(el){ return el.getView()});
console.log(viewsList);
return viewsList;
}
View.prototype.initialize = function () {
this.subViews = [];
this.domEvents = [];
this.strings = {};
this.props.tagName = 'section';
this.props.classNameView = 'view';
return this;
};
//View.prototype.createCSS = View.createCSS;
View.prototype.createGUI = function (appendTo) {
if (!this.node) {
this.createMarkup();
this.renderViews();
this.applyCostumGUI();
this.rgisterEvents();
}
if (appendTo) {
appendTo.appendChild(this.node);
}
return this.node;
};
View.prototype.createMarkup = function () {
var view = this;
this.node = document.createElement(this.props.tagName);
this.node.getView = function () {
return view;
};
this.node.className = this.props.classNameView;
return this.node;
};
View.prototype.renderViews = function () {
for (var i = 0; i < this.subViews.length; i++) {
this.node.appendChild(this.subViews[i].createGUI());
}
};
View.prototype.applyCostumGUI = function () {
if (this.costumGUI) {
return this.costumGUI.apply(this, this);
}
};
View.prototype.getSubView = function (index) {
return this.subViews[index];
};
View.prototype.addSubView = function (view) {
view.parentView = this;
this.subViews.push(view);
view.createGUI(this.node);
return view;
};
View.prototype.removeSubView = function (index) {
var view = this.subViews.splice(index, 1);
if (view.length) {
view = view[0];
delete view.parentView;
this.node.removeChild(view.node);
return view;
}
};
View.prototype.replaceSubView = function (index) {
var view = this.subViews.splice(index, 1);
if (view.length) {
view = view[0];
delete view.parentView;
this.node.removeChild(view.node);
return view;
}
};
View.prototype.handleDomEvents = function (type, node, e) {
if (node !== this.node) {
this.log('target is not node');
}
this.log('DomEvent', this, type, node, e);
};
View.prototype.rgisterEvents = function () {
var view = this;
var fnHandler = function (e) {
if (!e.cancelBubble) {
view.handleDomEvents(e.type, this, e);
}
};
for (var i = 0; i < this.domEvents.length; i++) {
this.node.addEventListener(this.domEvents[i], fnHandler, false);
}
};
var BoxView = View.create('BoxView');
BoxView.prototype.initialize = function (o) {
this.props.classNameView += ' box-view';
this.setInRow(o.inRow);
};
BoxView.prototype.setInRow = function (count) {
this.props.inRow = count || 1;
this.applyBox();
return this.node;
};
BoxView.prototype.addSubView = function (view) {
View.prototype.addSubView.call(this, view);
this.applyBox();
return this.node;
};
BoxView.prototype.applyBox = function () {
var viewNode;
for (var i = 0; i < this.subViews.length; i++) {
viewNode = this.subViews[i].node;
if (viewNode && !viewNode.classList.contains('box-view-node') || viewNode.dataset.inRow !== this.props.inRow) {
viewNode.dataset.inRow = this.props.inRow;
viewNode.classList.add('box-view-node');
viewNode.style.cssText = 'width:'+ 100/this.props.inRow +'%;';
}
}
};
var NodeView = View.create('NodeView');
NodeView.prototype.initialize = function (node) {
this.props.classNameView += ' node-view';
this.data.element = node;
};
NodeView.prototype.costumGUI = function () {
if (typeof this.data.element === 'string') {
this.node.innerHTML = this.data.element;
} else {
this.node.appndChild(this.data.element);
}
};
var TextView = View.create('TextView');
TextView.prototype.initialize = function (tagName, text) {
this.data.text = text;
this.props.tagName = tagName;
this.props.classNameView += ' text-view';
};
TextView.prototype.costumGUI = function () {
if (typeof this.data.text === 'string') {
this.node.textContent = this.data.text;
}
};
var ListView = View.create('ListView');
window.ListView = ListView;
ListView.prototype.initialize = function (repeatElement) {
this.data.repeatElement = repeatElement;
this.props.tagName = 'ul';
this.props.classNameView += ' list-view';
};
ListView.prototype.costumGUI = function () {
for (var i = 0; i < this.data.repeatElement.length; i++) {
this.addSubView(new TextView('li', this.data.repeatElement[i]+''));
}
};
var SimpleListView = View.create('SimpleListView');
window.SimpleListView = SimpleListView;
SimpleListView.prototype.initialize = function (repeatElement) {
this.data.repeatElement = repeatElement;
this.props.tagName = 'ul';
this.props.classNameView += ' simple-list-view';
};
SimpleListView.prototype.costumGUI = function () {
var r = '';
for (var i = 0; i < this.data.repeatElement.length; i++) {
r += '<li>' + this.data.repeatElement[i] + '</li>'
}
this.node.innerHTML = r;
};
var myView = BoxView.create('myView');
myView.prototype.initialize = function (o) {
this.domEvents = ['click', 'change'];
this.addSubView(new TextView('h3', o.title));
this.addSubView(new TextView('p', o.text));
this.addSubView(new ListView(o.list));
this.addSubView(new SimpleListView(o.list));
this.createGUI(o.appendTo);
this.addListener('propChange', function () {
console.log(this, arguments);
});
};
myView.prototype.costumGUI = function () {
var el = document.createElement('input');
//this.node.appendChild(el);
};
myView.prototype.handleDomEvents = function (type, node, e) {
this.log(type, node, e, e.target);
e.stopPropagation();
};
window.myViewInstance = new myView({
appendTo : document.body,
inRow : 3,
title : 'Hi this is myView',
text : 'this is some text',
list : ['item1', 'item2', 'item3', 'item4'],
});
var myViewInstance2 = new myView({
appendTo : document.body,
inRow : 3,
title : 'Hi this is myView',
text : 'this is some text',
list : ['item1', 'item2', 'item3', 'item4'],
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment