VulpesOS/gaia/apps/camera/bower_components/view/index.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

292 lines
No EOL
5.9 KiB
JavaScript
Executable file

(function(define){define(function(require,exports,module){
'use strict';
/**
* Module Dependencies
*/
var events = require('evt');
/**
* Locals
*/
var counter = 1;
var noop = function() {};
/**
* Exports
*/
module.exports = View;
/**
* Base view class. Accepts
* or creates a root element
* which we template into.
*
* @constructor
*/
function View(options) {
options = options || {};
this.el = options.el || this.el || document.createElement(this.tag);
this.el.id = this.el.id || ('view' + counter++);
this.name = options.name || this.name;
this.els = {};
if (!this.el.className) {
if (this.name) this.el.className = this.name;
if (this.className) this.el.className += ' ' + this.className;
}
bindAll(this);
this.initialize.apply(this, arguments);
}
/**
* Base view prototype,
* mixed in event emitter.
*
* @type {Object}
*/
events(View.prototype);
// Allow for 'emit' or
// 'fire' to trigger events
View.prototype.fire = View.prototype.fire || View.prototype.emit;
/**
* Default tagName
*
* @type {String}
*/
View.prototype.tag = 'div';
View.prototype.name = 'noname';
/**
* Appends the root element
* to the given parent.
*
* @param {Element} parent
* @return {View}
*/
View.prototype.appendTo = function(parent) {
if (!parent) return this;
parent.appendChild(this.el);
this.fire('inserted');
return this;
};
/**
* Prepends the root element
* to the given parent.
*
* @param {Element} parent
* @return {View}
*/
View.prototype.prependTo = function(parent) {
if (!parent) return this;
var first = parent.firstChild;
if (first) parent.insertBefore(this.el, first);
else this.appendTo(parent);
this.fire('inserted');
return this;
};
/**
* Convenient shorthand
* querySelector.
*
* @param {String} query
* @return { Element | null}
*/
View.prototype.find = function(query) {
return this.el.querySelector(query);
};
/**
* Removes the element from
* its current DOM location.
*
* @param {Object} options
* @return {View}
*/
View.prototype.remove = function(options) {
var silent = options && options.silent;
var parent = this.el.parentNode;
if (!parent) return this;
parent.removeChild(this.el);
if (!silent) this.fire('remove');
return this;
};
View.prototype.set = function(key, value) {
value = value === undefined ? '' : value;
this.el.setAttribute(toDashed(key), value);
};
View.prototype.get = function(key) {
return this.el.getAttribute(key);
};
/**
* Returns a function that when called
* will .set() the given key.
*
* If a value is passed to .setter(),
* that value will always be used
* when the returned function is called.
* Else the value passed to the given
* function will be used.
*
* Example:
*
* var setter = this.setter('key', 'value');
* setter(); //=> this.set('key', 'value');
* setter('value2'); //=> this.set('key', 'value');
*
* var setter = this.setter('key');
* setter('value'); //=> this.set('key', 'value');
* setter(); //=> this.set('key');
*
* @param {String} key
* @param {*} value
* @return {Function}
*/
View.prototype.setter = function(key, forced) {
var self = this;
return function(passed) {
var value = forced !== undefined ? forced : passed;
self.set(key, value);
};
};
View.prototype.enable = function(key, value) {
switch(arguments.length) {
case 0:
value = true;
key = 'enabled';
break;
case 1:
if (typeof key === 'boolean') {
value = key;
key = 'enabled';
} else {
value = true;
key = key ? key + '-enabled' : 'enabled';
}
break;
default:
key = key ? key + '-enabled' : 'enabled';
}
this.set(key, !!value);
};
View.prototype.disable = function(key) {
this.enable(key, false);
};
View.prototype.enabler = function(key) {
return (function(value) { this.enable(key, value); }).bind(this);
};
View.prototype.hide = function(key) {
this.toggle(key, false);
};
View.prototype.show = function(key) {
this.toggle(key, true);
};
View.prototype.toggle = function(key, value) {
if (arguments.length === 1 && typeof key === 'boolean') {
value = key;
key = '';
} else {
key = key ? key + '-' : '';
}
this.el.classList.toggle(key + 'hidden', !value);
this.el.classList.toggle(key + 'visible', value);
};
/**
* Removes the element from
* it's current context, firing
* a 'destroy' event to allow
* views to perform cleanup.
*
* Then clears any internal
* references to aid GC.
*
* @return {[type]} [description]
*/
View.prototype.destroy = function(options) {
var noRemove = options && options.noRemove;
if (!noRemove) this.remove();
this.fire('destroy');
this.el = null;
};
View.prototype.toString = function() {
return '[object View]';
};
// Overwrite as required
View.prototype.initialize = noop;
View.prototype.template = function() { return ''; };
/**
* Extends the base view
* class with the given
* properties.
*
* TODO: Pull this out to
* standalone module.
*
* @param {Object} properties
* @return {Function}
*/
View.extend = function(props) {
var Parent = this;
// The extended constructor
// calls the parent constructor
var Child = function() {
Parent.apply(this, arguments);
};
Child.prototype = Object.create(Parent.prototype);
Child.extend = View.extend;
mixin(Child.prototype, props);
return Child;
};
function toDashed(s) {
return s.replace(/\W+/g, '-')
.replace(/([a-z\d])([A-Z])/g, '$1-$2')
.toLowerCase();
}
function mixin(a, b) {
for (var key in b) { a[key] = b[key]; }
return a;
}
function bindAll(object) {
var key;
var fn;
for (key in object) {
fn = object[key];
if (typeof fn === 'function') {
object[key] = fn.bind(object);
}
}
}
});})((function(n,w){return typeof define=='function'&&define.amd?
define:typeof module=='object'?function(c){c(require,exports,module);}:function(c){
var m={exports:{}},r=function(n){return w[n];};w[n]=c(r,m.exports,m)||m.exports;};})('view',this));