You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
510 lines
22 KiB
510 lines
22 KiB
// dna.js Template Cloner ~~ v0.2.9
|
|
// MIT/GPLv3 ~~ dnajs.org/license.html
|
|
// Copyright (c) 2013-2014 Center Key Software and other contributors
|
|
|
|
var dna = {
|
|
// API:
|
|
// dna.clone()
|
|
// dna.cloneSubTemplate()
|
|
// dna.load()
|
|
// dna.getModel()
|
|
// dna.empty()
|
|
// dna.mutate()
|
|
// dna.mutateAll()
|
|
// dna.destroy()
|
|
// dna.getClone()
|
|
// dna.getClones()
|
|
// dna.bye()
|
|
// dna.registerInitializer()
|
|
// dna.clearInitializers()
|
|
// dna.info()
|
|
// See: http://dnajs.org/manual.html#api
|
|
clone: function(name, data, options) {
|
|
var settings = { fade: false, top: false, container: null, empty: false,
|
|
html: false, callback: null };
|
|
$.extend(settings, options);
|
|
var template = dna.store.getTemplate(name);
|
|
if (template.nested && !settings.container)
|
|
dna.core.berserk('Container missing for nested template: ' + name);
|
|
if (settings.empty)
|
|
dna.empty(name);
|
|
var list = data instanceof Array ? data : [data];
|
|
var clones = $();
|
|
for (var i = 0; i < list.length; i++){
|
|
console.log('-----------------------------')
|
|
console.log(template)
|
|
console.log(list[i])
|
|
console.log(i+1)
|
|
console.log(settings)
|
|
clones = clones.add(dna.core.replicate(template, list[i], i + 1, settings));
|
|
}
|
|
console.log('//////')
|
|
console.log(clones)
|
|
console.log('//////')
|
|
return clones;
|
|
},
|
|
cloneSubTemplate: function(holderClone, arrayField, data, options) {
|
|
var name = dna.compile.subTemplateName(holderClone, arrayField);
|
|
var selector = '.dna-contains-' + name;
|
|
var settings = { container: holderClone.find(selector).addBack(selector) };
|
|
$.extend(settings, options);
|
|
dna.clone(name, data, settings);
|
|
var array = dna.getModel(holderClone)[arrayField];
|
|
function append() { array.push(this); }
|
|
$.each(data instanceof Array ? data : [data], append);
|
|
return holderClone;
|
|
},
|
|
load: function(name, url, options) {
|
|
function processJson(data) { dna.core.unload(name, data, options); }
|
|
return $.getJSON(url, processJson);
|
|
},
|
|
getModel: function(nameOrClone) {
|
|
function getModelArray() {
|
|
var model = [];
|
|
dna.getClones(nameOrClone).each(
|
|
function() { model.push($(this).data('dna-model')); });
|
|
return model;
|
|
}
|
|
return nameOrClone instanceof jQuery ?
|
|
dna.getClone(nameOrClone).data('dna-model') : getModelArray();
|
|
},
|
|
empty: function(name, options) {
|
|
var settings = { fade: false };
|
|
$.extend(settings, options);
|
|
var clones = dna.store.getTemplate(name).container.find('.dna-clone');
|
|
return settings.fade ? dna.ui.slideFadeDelete(clones) : clones.remove();
|
|
},
|
|
mutate: function(clone, data, options) {
|
|
var settings = { html: false };
|
|
$.extend(settings, options);
|
|
clone = dna.getClone(clone);
|
|
if (!data)
|
|
data = dna.getModel(clone);
|
|
dna.core.inject(clone, data, null, settings);
|
|
return clone;
|
|
},
|
|
mutateAll: function(name) {
|
|
function mutate() { dna.mutate($(this)); }
|
|
return dna.getClones(name).each(mutate);
|
|
},
|
|
destroy: function(clone, options) {
|
|
var settings = { fade: false };
|
|
$.extend(settings, options);
|
|
clone = dna.getClone(clone);
|
|
function removeArrayItem(holder, field) {
|
|
var arrayClones = holder.children('.' + dna.compile.subTemplateName(holder, field));
|
|
dna.getModel(holder)[field].splice(arrayClones.index(clone), 1);
|
|
}
|
|
if (clone.hasClass('dna-array'))
|
|
removeArrayItem(clone.parent(), clone.data().dnaRules.array);
|
|
return settings.fade ? dna.ui.slideFadeDelete(clone) : clone.remove();
|
|
},
|
|
getClone: function(elem) {
|
|
return elem instanceof jQuery ? elem.closest('.dna-clone') : $();
|
|
},
|
|
getClones: function(name) {
|
|
return dna.store.getTemplate(name).container.children().filter('.dna-clone');
|
|
},
|
|
bye: function(elemOrEventOrIndex) {
|
|
return dna.destroy(dna.ui.toElem(elemOrEventOrIndex, this), { fade: true });
|
|
},
|
|
registerInitializer: function(func, options) {
|
|
var settings = { onDocumentLoad: true };
|
|
$.extend(settings, options);
|
|
if (settings.onDocumentLoad)
|
|
dna.util.apply(func, [settings.selector ? $(settings.selector).not('.dna-template ' +
|
|
settings.selector).addClass('dna-initialized') : $(document)].concat(settings.params));
|
|
return dna.events.initializers.push(
|
|
{ func: func, selector: settings.selector, params: settings.params });
|
|
},
|
|
clearInitializers: function() {
|
|
dna.events.initializers = [];
|
|
},
|
|
info: function() {
|
|
var names = Object.keys(dna.store.templates);
|
|
console.log('~~ dns.js v0.2.9 ~~');
|
|
console.log('templates:', names.length);
|
|
console.log('names:', names);
|
|
console.log('store:', dna.store.templates);
|
|
console.log('initializers:', dna.events.initializers.length);
|
|
return navigator.appVersion;
|
|
}
|
|
};
|
|
|
|
dna.util = {
|
|
toCamel: function(codeStr) { //example: 'ready-set-go' ==> 'readySetGo'
|
|
function hump(match, char) { return char.toUpperCase(); }
|
|
return ('' + codeStr).replace(/\-(.)/g, hump);
|
|
},
|
|
toCode: function(camelCaseStr) { //example: 'readySetGo' ==> 'ready-set-go'
|
|
function dash(word) { return '-' + word.toLowerCase(); }
|
|
return ('' + camelCaseStr).replace(/([A-Z])/g, dash).replace(/\s|^-/g, '');
|
|
},
|
|
value: function(data, field) { //example: dna.util.value({ a: { b: 7 }}, 'a.b'); ==> 7
|
|
if (typeof field === 'string')
|
|
field = field.split('.');
|
|
return (data === null || data === undefined || field === undefined) ? null :
|
|
(field.length === 1 ? data[field[0]] : this.value(data[field[0]], field.slice(1)));
|
|
},
|
|
realTruth: function(value) { //returns a boolean
|
|
// Example true values: true, 7, '7', [5], 't', 'T', 'TRue', {}, 'Colbert'
|
|
// Example false values: false, 0, '0', [], 'f', 'F', 'faLSE', null, undefined, NaN
|
|
function falseyStr() { return /^(f|false|0)$/i.test(value); }
|
|
function emptyArray() { return value instanceof Array && value.length === 0; }
|
|
return value ? !emptyArray() && !falseyStr() : false;
|
|
},
|
|
apply: function(func, params) { //calls func (string name or actual function) passing in params
|
|
// Example: dna.util.apply('app.cart.buy', 7); ==> app.cart.buy(7);
|
|
var args = [].concat(params);
|
|
var elem = args[0], result;
|
|
function contextApply(obj, names) {
|
|
if (!obj || (names.length == 1 && typeof obj[names[0]] !== 'function'))
|
|
dna.core.berserk('Callback function not found: ' + func);
|
|
else if (names.length == 1)
|
|
result = obj[names[0]].apply(elem, args); //'app.cart.buy' ==> window['app']['cart']['buy']
|
|
else
|
|
contextApply(obj[names[0]], names.slice(1));
|
|
}
|
|
if (elem instanceof jQuery && elem.length === 0)
|
|
result = elem;
|
|
else if (typeof func === 'function')
|
|
result = func.apply(elem, args);
|
|
else if (elem && elem[func])
|
|
result = elem[func](args[1], args[2], args[3]);
|
|
else if (func === '' || $.inArray(typeof func, ['number', 'boolean']) !== -1)
|
|
dna.core.berserk('Invalid callback function: ' + func);
|
|
else if (typeof func === 'string' && func.length > 0)
|
|
contextApply(window, func.split('.'));
|
|
return result;
|
|
}
|
|
};
|
|
|
|
dna.ui = {
|
|
toElem: function(elemOrEventOrIndex, that) {
|
|
return elemOrEventOrIndex instanceof jQuery ? elemOrEventOrIndex :
|
|
elemOrEventOrIndex ? $(elemOrEventOrIndex.target) : $(that);
|
|
},
|
|
deleteElem: function(elemOrEventOrIndex) { //example: $('.box').fadeOut(dna.ui.deleteElem);
|
|
return dna.ui.toElem(elemOrEventOrIndex, this).remove();
|
|
},
|
|
slideFade: function(elem, callback, show) {
|
|
var obscure = { opacity: 0.0, transition: 'opacity 0s ease 0s' };
|
|
var easyIn = { opacity: 1.0, transition: 'opacity 0.4s ease-in' };
|
|
var easyOut = { opacity: 0.0, transition: 'opacity 0.4s ease-out' };
|
|
var reset = { transition: 'opacity 0s ease 0s' };
|
|
function clearOpacityTransition() { elem.css(reset); }
|
|
window.setTimeout(clearOpacityTransition, 1000); //keep clean for other animations
|
|
if (show)
|
|
elem.css(obscure).hide().slideDown({ complete: callback }).css(easyIn);
|
|
else
|
|
elem.css(easyOut).slideUp({ complete: callback });
|
|
return elem;
|
|
},
|
|
slideFadeIn: function(elem, callback) {
|
|
return dna.ui.slideFade(elem, callback, true);
|
|
},
|
|
slideFadeOut: function(elem, callback) {
|
|
return dna.ui.slideFade(elem, callback, false);
|
|
},
|
|
slideFadeToggle: function(elem, callback) {
|
|
return dna.ui.slideFade(elem, callback, elem.is(':hidden'));
|
|
},
|
|
slideFadeDelete: function(elem) {
|
|
return dna.ui.slideFadeOut(elem, dna.ui.deleteElem);
|
|
},
|
|
slidingFlasher: function(elem, callback) {
|
|
return elem.is(':hidden') ? dna.ui.slideFadeIn(elem, callback) : elem.hide().fadeIn();
|
|
}
|
|
};
|
|
|
|
dna.compile = {
|
|
// Pre-compile Example Post-compile class + data().dnaRules
|
|
// ----------- -------------------------------- ------------------------------------
|
|
// templates <p id=ad class=dna-template> class=dna-clone
|
|
// arrays <p data-dna-array=~~tags~~> class=dna-nucleotide + array='tags'
|
|
// fields <p>~~tag~~</p> class=dna-nucleotide + text='tag'
|
|
// attributes <p id=~~num~~> class=dna-nucleotide + attrs=['id', ['', 'num', '']]
|
|
// rules <p data-dna-truthy=~~on~~> class=dna-nucleotide + truthy='on'
|
|
// attr rules <p data-dna-attr-src=~~url~~> class=dna-nucleotide + attrs=['src', ['', 'url', '']]
|
|
// prop rules <input data-dna-prop-checked=~~on~~> class=dna-nucleotide + props=['checked', 'on']
|
|
//
|
|
// Rules data().dnaRules
|
|
// --------------------------------------------- ---------------
|
|
// data-dna-class=~~field,name-true,name-false~~ class=['field','name-true','name-false']
|
|
// data-dna-attr-{NAME}=pre~~field~~post attrs=['{NAME}', ['pre', 'field', 'post']]
|
|
// data-dna-prop-{NAME}=pre~~field~~post props=['{NAME}', 'field']
|
|
// data-dna-require=~~field~~ require='field'
|
|
// data-dna-missing=~~field~~ missing='field'
|
|
// data-dna-truthy=~~field~~ truthy='field'
|
|
// data-dna-falsey=~~field~~ falsey='field'
|
|
//
|
|
regexDnaField: /^[\s]*(~~|\{\{).*(~~|\}\})[\s]*$/, //example: ~~title~~
|
|
regexDnaBasePair: /~~|{{|}}/, //matches the '~~' string
|
|
regexDnaBasePairs: /~~|\{\{|\}\}/g, //matches the two '~~' strings so they can be removed
|
|
setupNucleotide: function(elem) {
|
|
if (elem.data().dnaRules === undefined)
|
|
elem.data().dnaRules = {};
|
|
return elem.addClass('dna-nucleotide');
|
|
},
|
|
isDnaField: function() {
|
|
var firstNode = $(this)[0].childNodes[0];
|
|
return firstNode && firstNode.nodeValue &&
|
|
firstNode.nodeValue.match(dna.compile.regexDnaField);
|
|
},
|
|
field: function() {
|
|
// Example:
|
|
// <p>~~name~~</p> ==> <p class=dna-nucleotide data-dnaRules={ text: 'name' }></p>
|
|
var elem = dna.compile.setupNucleotide($(this));
|
|
console.log(elem)
|
|
elem.data().dnaRules.text = $.trim(elem.text()).replace(dna.compile.regexDnaBasePairs, '');
|
|
return elem.empty();
|
|
},
|
|
propsAndAttrs: function() {
|
|
// Examples:
|
|
// <option data-dna-prop-selected=~~set~~> ==> <option class=dna-nucleotide + data-dnaRules={ props: ['selected', 'set'] }>
|
|
// <p id=~~num~~> ==> <p class=dna-nucleotide + data-dnaRules={ attrs: ['id', ['', 'num', '']] }>
|
|
// <p data-dna-attr-src=~~url~~> ==> <p class=dna-nucleotide + data-dnaRules={ attrs: ['src', ['', 'url', '']] }>
|
|
var elem = $(this);
|
|
var props = [];
|
|
var attrs = [];
|
|
var names = [];
|
|
function compile() {
|
|
if ((/^data-dna-prop-/).test(this.name))
|
|
props.push(this.name.replace(/^data-dna-prop-/, ''),
|
|
this.value.replace(dna.compile.regexDnaBasePairs, ''));
|
|
else if (this.value.split(dna.compile.regexDnaBasePair).length === 3)
|
|
attrs.push(this.name.replace(/^data-dna-attr-/, ''),
|
|
this.value.split(dna.compile.regexDnaBasePair));
|
|
else
|
|
return;
|
|
names.push(this.name);
|
|
}
|
|
$.each(elem.get(0).attributes, compile);
|
|
if (props.length > 0)
|
|
dna.compile.setupNucleotide(elem).data().dnaRules.props = props;
|
|
if (attrs.length > 0)
|
|
dna.compile.setupNucleotide(elem).data().dnaRules.attrs = attrs;
|
|
return elem.removeAttr(names.join(' '));
|
|
},
|
|
getDataField: function(elem, type) {
|
|
// Example:
|
|
// <p dna-array=~~tags~~>, 'array' ==> 'tags'
|
|
return $.trim(elem.data('dna-' + type).replace(dna.compile.regexDnaBasePairs, ''));
|
|
},
|
|
subTemplateName: function(holder, arrayField) { //holder can be element or template name
|
|
// Example: subTemplateName('book', 'authors') ==> 'book-authors-instance'
|
|
var mainTemplateName = holder instanceof jQuery ?
|
|
dna.getClone(holder).data().dnaRules.template : holder;
|
|
return mainTemplateName + '-' + arrayField + '-instance';
|
|
},
|
|
rules: function(elems, type, isList) {
|
|
// Example:
|
|
// <p data-dna-require=~~title~~>, 'require' ==> <p data-dnaRules={ require: 'title' }>
|
|
function add() {
|
|
var elem = dna.compile.setupNucleotide($(this));
|
|
var field = dna.compile.getDataField(elem, type);
|
|
elem.data().dnaRules[type] = isList ? field.split(',') : field;
|
|
}
|
|
return elems.filter('[data-dna-' + type + ']').each(add).removeAttr('data-dna-' + type);
|
|
},
|
|
template: function(name) { //prepare template to be cloned
|
|
var elem = $('#' + name);
|
|
if (!elem.length)
|
|
dna.core.berserk('Template not found: ' + name);
|
|
function saveName() { $(this).data().dnaRules = { template: $(this).attr('id') }; }
|
|
elem.find('.dna-template').addBack().each(saveName).removeAttr('id');
|
|
var elems = elem.find('*').addBack();
|
|
console.log(dna.compile.field)
|
|
elems.filter(dna.compile.isDnaField).each(dna.compile.field);
|
|
dna.compile.rules(elems, 'array').addClass('dna-array');
|
|
dna.compile.rules(elems, 'class', true);
|
|
dna.compile.rules(elems, 'require');
|
|
dna.compile.rules(elems, 'missing');
|
|
dna.compile.rules(elems, 'truthy');
|
|
dna.compile.rules(elems, 'falsey');
|
|
elems.each(dna.compile.propsAndAttrs);
|
|
return dna.store.stash(elem);
|
|
}
|
|
};
|
|
|
|
dna.store = {
|
|
// Handles storage and retrieval of templates
|
|
templates: {},
|
|
stash: function(elem) {
|
|
var name = elem.data().dnaRules.template;
|
|
function move() {
|
|
var elem = $(this);
|
|
var name = elem.data().dnaRules.template;
|
|
var template = {
|
|
name: name,
|
|
elem: elem,
|
|
container: elem.parent().addClass('dna-container').addClass('dna-contains-' + name),
|
|
nested: elem.parent().closest('.dna-clone').length !== 0,
|
|
index: elem.index(),
|
|
clones: 0
|
|
};
|
|
dna.store.templates[name] = template;
|
|
elem.removeClass('dna-template').addClass('dna-clone').addClass(name).detach();
|
|
}
|
|
function prepLoop() {
|
|
// Pre (sub-template array loops -- data-dna-array):
|
|
// class=dna-array data().dnaRules.array='field'
|
|
// Post (elem):
|
|
// data().dnaRules.template='{NAME}-{FIELD}-instance'
|
|
// Post (container)
|
|
// class=dna-nucleotide + data().dnaRules.loop={ name: '{NAME}-{FIELD}-instance', field: 'field' }
|
|
var elem = $(this);
|
|
var field = elem.data().dnaRules.array;
|
|
var sub = dna.compile.subTemplateName(name, field);
|
|
dna.compile.setupNucleotide(elem.parent()).data().dnaRules.loop =
|
|
{ name: sub, field: field };
|
|
elem.data().dnaRules.template = sub;
|
|
}
|
|
elem.find('.dna-template').addBack().each(move);
|
|
elem.find('.dna-array').each(prepLoop).each(move);
|
|
return dna.store.templates[name];
|
|
},
|
|
getTemplate: function(name) {
|
|
return dna.store.templates[name] || dna.compile.template(name);
|
|
}
|
|
};
|
|
|
|
dna.events = {
|
|
initializers: [], //example: [{ func: 'app.bar.setup', selector: '.progress-bar' }]
|
|
elementSetup: function(root, data) {
|
|
// Example (outside of template):
|
|
// <p class=dna-setup data-dna-setup=app.cart.setup>
|
|
// Example (within template):
|
|
// <select data-dna-setup=app.dropDown.setup>
|
|
function setup() { dna.util.apply($(this).data('dna-setup'), [$(this), data]); }
|
|
var selector = '[data-dna-setup]';
|
|
var elems = root ? root.find(selector).addBack(selector) : $('.dna-setup');
|
|
return elems.each(setup).addClass('dna-initialized');
|
|
},
|
|
runInitializers: function(elem, data) {
|
|
// Executes both the data-dna-setup functions and the registered initializers
|
|
dna.events.elementSetup(elem, data);
|
|
function init() { dna.util.apply(this.func, [(this.selector ?
|
|
elem.find(this.selector).addBack(this.selector) : elem).addClass('dna-initialized')]
|
|
.concat(this.params)); }
|
|
$.each(dna.events.initializers, init);
|
|
return elem;
|
|
},
|
|
runner: function(elem, type, event) {
|
|
// Finds elements for given type and executes callback passing in the element and the event
|
|
// Types: click|change|key-up|key-down|key-press|enter-key
|
|
elem = elem.closest('[data-dna-' + type + ']');
|
|
return dna.util.apply(elem.data('dna-' + type), [elem, event]);
|
|
},
|
|
handle: function(event) {
|
|
return dna.events.runner($(event.target), event.type.replace('key', 'key-'), event);
|
|
},
|
|
handleEnterKey: function(event) {
|
|
return event.which === 13 ? dna.events.runner($(event.target), 'enter-key', event) : null;
|
|
},
|
|
setup: function() {
|
|
$(document)
|
|
.click(dna.events.handle)
|
|
.change(dna.events.handle)
|
|
.keyup(dna.events.handle)
|
|
.keyup(dna.events.handleEnterKey)
|
|
.keydown(dna.events.handle)
|
|
.keypress(dna.events.handle);
|
|
dna.events.elementSetup();
|
|
}
|
|
};
|
|
|
|
$(dna.events.setup);
|
|
|
|
dna.core = {
|
|
inject: function(clone, data, count, settings) {
|
|
// Inserts data into clone and runs rules
|
|
function injectField(elem, field) {
|
|
var value = typeof data === 'object' ? dna.util.value(data, field) :
|
|
field === '[count]' ? count : field === '[value]' ? data : null;
|
|
var printableTypes = ['string', 'number', 'boolean'];
|
|
function printable(value) { return $.inArray(typeof value, printableTypes) !== -1; }
|
|
if (printable(value))
|
|
elem = settings.html ? elem.html(value) : elem.text(value);
|
|
}
|
|
function injectProps(elem, props) {
|
|
for (var x = 0; x < props.length / 2; x++)
|
|
elem.prop(props[x*2], dna.util.realTruth(dna.util.value(data, props[x*2 + 1])));
|
|
}
|
|
function injectAttrs(elem, attrs) {
|
|
for (var x = 0; x < attrs.length / 2; x++) {
|
|
var attr = attrs[x*2];
|
|
var parts = attrs[x*2 + 1]; //ex: 'J~~code.num~~' --> ['J', 'code.num', '']
|
|
var value = [parts[0], dna.util.value(data, parts[1]), parts[2]].join('');
|
|
elem.attr(attr, value);
|
|
if (attr === 'value')
|
|
elem.val(value);
|
|
}
|
|
}
|
|
function injectClass(elem, classList) {
|
|
// classList = ['field', 'class-true', 'class-false']
|
|
var value = dna.util.value(data, classList[0]);
|
|
var truth = dna.util.realTruth(value);
|
|
if (classList.length === 1) {
|
|
elem.addClass(value);
|
|
}
|
|
else if (classList.length > 1) {
|
|
elem.toggleClass(classList[1], truth);
|
|
if (classList[2])
|
|
elem.toggleClass(classList[2], !truth);
|
|
}
|
|
}
|
|
function processLoop(elem, loop) {
|
|
var dataArray = dna.util.value(data, loop.field);
|
|
if (dataArray)
|
|
dna.clone(loop.name, dataArray, { container: elem });
|
|
}
|
|
function process() {
|
|
var elem = $(this);
|
|
var dnaRules = elem.data().dnaRules;
|
|
if (dnaRules.text)
|
|
injectField(elem, dnaRules.text);
|
|
if (dnaRules.props)
|
|
injectProps(elem, dnaRules.props);
|
|
if (dnaRules.attrs)
|
|
injectAttrs(elem, dnaRules.attrs);
|
|
if (dnaRules.class)
|
|
injectClass(elem, dnaRules.class);
|
|
if (dnaRules.require)
|
|
elem.toggle(dna.util.value(data, dnaRules.require) !== undefined);
|
|
if (dnaRules.missing)
|
|
elem.toggle(dna.util.value(data, dnaRules.missing) === undefined);
|
|
if (dnaRules.truthy)
|
|
elem.toggle(dna.util.realTruth(dna.util.value(data, dnaRules.truthy)));
|
|
if (dnaRules.falsey)
|
|
elem.toggle(!dna.util.realTruth(dna.util.value(data, dnaRules.falsey)));
|
|
if (dnaRules.loop)
|
|
processLoop(elem, dnaRules.loop);
|
|
}
|
|
clone.find('.dna-array').remove();
|
|
clone.find('.dna-nucleotide').addBack('.dna-nucleotide').each(process);
|
|
return clone.data('dna-model', data);
|
|
},
|
|
replicate: function(template, data, count, settings) { //make and setup the clone
|
|
var clone = template.elem.clone(true, true);
|
|
template.clones++;
|
|
dna.core.inject(clone, data, count, settings);
|
|
var selector = '.dna-contains-' + template.name;
|
|
var container = settings.container ?
|
|
settings.container.find(selector).addBack(selector) : template.container;
|
|
container[settings.top ? 'prepend' : 'append'](clone);
|
|
dna.events.runInitializers(clone, data);
|
|
if (settings.callback)
|
|
settings.callback(clone, data);
|
|
if (settings.fade)
|
|
dna.ui.slideFadeIn(clone);
|
|
return clone;
|
|
},
|
|
unload: function(name, data, options) { //use rest data to make clone
|
|
if (!data.error)
|
|
dna.clone(name, data, options);
|
|
},
|
|
berserk: function(message) { //oops, file a tps report
|
|
throw 'dna.js error -> ' + message;
|
|
}
|
|
};
|
|
|