Ejemplo n.º 1
0
Reduce = function (list, cb, initial, initialized) {
	this.list = list;
	this.cb = cb;
	this.initialized = initialized;
	this.length = toNaturalNumber(list.length);

	initial = assimilate(initial);
	if (isPromise(initial)) {
		if (!initial.resolved) {
			assign(this, deferred());
			initial.done(
				function (resolvedInitial) {
					this.value = resolvedInitial;
					this.init();
				}.bind(this),
				this.reject
			);
			return this.promise;
		}
		this.value = initial.value;
		if (initial.failed) return initial;
	} else {
		this.value = initial;
	}

	return this.init();
};
module.exports = function () {
	var assign = Object.assign, obj;
	if (typeof assign !== 'function') return false;
	obj = { foo: 'raz' };
	assign(obj, { bar: 'dwa' }, { trzy: 'trzy' });
	return (obj.foo + obj.bar + obj.trzy) === 'razdwatrzy';
};
Ejemplo n.º 3
0
module.exports = function (fn/*, options*/) {
	var factory, memoized;
	if (fn.__memoized__) return fn;
	memoized = memoize(fn, assign(Object(arguments[1]), { refCounter: true }));
	factory = function () {
		var watcher, emitter, pipe, args, def;
		args = arguments;
		watcher = memoized.apply(this, arguments);
		if (isPromise(watcher)) {
			def = deferred();
			emitter = def.promise;
			def.resolve(watcher);
		} else {
			emitter = ee();
		}
		pipe = eePipe(watcher, emitter);
		emitter.close = function () {
			emitter.close = noop;
			pipe.close();
			if (memoized.deleteRef.apply(this, args)) watcher.close();
		};
		return emitter;
	};
	factory.clear = memoized.delete;
	factory.__memoized__ = true;
	return factory;
};
Ejemplo n.º 4
0
readdir = function (path, options) {
	var lReaddir, globalRules;

	lReaddir = new Readdir();
	lReaddir.path = path;
	lReaddir.depth = isNaN(options.depth) ? 0 : toPosInt(options.depth);
	lReaddir.type = isValue(options.type) ? Object(options.type) : null;
	lReaddir.loose = Boolean(options.loose);
	lReaddir.pattern = isValue(options.pattern) ? new RegExp(options.pattern) : null;
	if (isValue(options.dirFilter)) {
		if (typeof options.dirFilter === "function") lReaddir.dirFilter = options.dirFilter;
		else lReaddir.dirFilter = RegExp.prototype.test.bind(new RegExp(options.dirFilter));
	}
	lReaddir.watch = options.watch;
	lReaddir.stream = Boolean(options.stream);

	if (options.globalRules) {
		globalRules = isArray(options.globalRules)
			? options.globalRules
			: String(options.globalRules).split(eolRe);
	}
	if (options.ignoreRules) {
		assign(
			lReaddir,
			getIsIgnored(
				isArray(options.ignoreRules) ? options.ignoreRules : [options.ignoreRules],
				globalRules, options.watch
			)
		);
	} else {
		lReaddir.globalRules = globalRules;
	}

	return lReaddir.init();
};
d.gs = function (dscr, get, set/*, options*/) {
	var c, e, options, desc;
	if (typeof dscr !== 'string') {
		options = set;
		set = get;
		get = dscr;
		dscr = null;
	} else {
		options = arguments[3];
	}
	if (get == null) {
		get = undefined;
	} else if (!isCallable(get)) {
		options = get;
		get = set = undefined;
	} else if (set == null) {
		set = undefined;
	} else if (!isCallable(set)) {
		options = set;
		set = undefined;
	}
	if (dscr == null) {
		c = true;
		e = false;
	} else {
		c = contains.call(dscr, 'c');
		e = contains.call(dscr, 'e');
	}

	desc = { get: get, set: set, configurable: c, enumerable: e };
	return !options ? desc : assign(normalizeOpts(options), desc);
};
Ejemplo n.º 6
0
Reduce = function (list, cb, initial, initialized) {
	this.list = list;
	this.cb = cb;
	this.initialized = initialized;
	this.length = list.length >>> 0;

	if (isPromise(initial)) {
		if (!initial.resolved) {
			assign(this, deferred());
			initial.end(function (initial) {
				this.value = initial;
				this.init();
			}.bind(this), this.resolve);
			return this.promise;
		}
		this.value = initial.value;
		if (isError(this.value)) {
			return initial;
		}
	} else {
		this.value = initial;
	}

	return this.init();
};
Ejemplo n.º 7
0
			this.optsPromise.on('change', function (nopts) {
				if (this.inputOptions) {
					nopts = filter(assign(nopts, this.inputOptions), Boolean);
				}
				nopts = parseOptions(nopts, this.linter.xlintId);
				if (!isCopy(this.options, nopts)) {
					this.options = nopts;
					if (this.promise.resolved) {
						this.filePromise.aside(this.onchange);
					}
				}
			}.bind(this));
Ejemplo n.º 8
0
module.exports = function (t, a) {
	var db   = new Database()
	  , Type = t(db)
	  , supportedLocales, haveEnLocale, havePlLocale, localeOptions;

	a.h1("Format");
	a(Type.format(0.78912), '0.79', "Less than 1");
	a(Type.format(56.78912), '56.79', "Tens");
	a(Type.format(456.78912), '456.79', "Hundreds");
	a(Type.format(3456.78912), '3\'456.79', "Thousands");
	a(Type.format(123456.78912), '123\'456.79', "Hundreds of thousands");
	a(Type.format(7123456.78912), '7\'123\'456.79', "Millions");

	if ((typeof Intl !== 'undefined') && (typeof Intl.NumberFormat === 'function')) {
		supportedLocales = Intl.NumberFormat.supportedLocalesOf(['en', 'pl'],
			{ localeMatcher: 'lookup' });
		haveEnLocale = arrayContains.call(supportedLocales, 'en');
		havePlLocale = arrayContains.call(supportedLocales, 'pl');

		a.h1("Locale support");

		if (haveEnLocale) {
			localeOptions = { locale: 'en', currency: 'USD' };

			a(Type.format(56.79, localeOptions), '$56.79');
			a(Type.format(56.79, assign({ currencyDisplay: 'code' }, localeOptions)), 'USD56.79');
			a(Type.format(56.79, assign({ currencyDisplay: 'name' }, localeOptions)), '56.79 US dollars');
		}

		if (havePlLocale) {
			localeOptions = { locale: 'pl', currency: 'PLN' };

			// Important: Those spaces between digits and symbols are no-brake spaces (Unicode: U+00A0)
			a(Type.format(56.79, localeOptions), '56,79 zł');
			a(Type.format(56.79, assign({ currencyDisplay: 'code' }, localeOptions)), '56,79 PLN');
			a(Type.format(56.79, assign({ currencyDisplay: 'name' }, localeOptions)),
				'56,79 złotego polskiego');
		}
	}
};
Ejemplo n.º 9
0
	createProto = function (proto, id, kind, object) {
		proto = create(proto);
		if (!object) object = proto;
		return defineProperties(proto, assign({
			__id__: d('', id),
			__valueId__: d('', id),
			_kind_: d('', kind),
			master: d('', object),
			object: d('', object),
			database: d('', db),
			toString: d('c', function () { return '[dbjs ' + this.__id__ + ']'; })
		}, protoProperties));
	};
Ejemplo n.º 10
0
DMap = function (list, cb, context) {
	this.list = list;
	this.cb = cb;
	this.context = context;
	this.result = new Array(list.length >>> 0);

	assign(this, deferred());
	every.call(list, this.process, this);
	if (!this.waiting) {
		return this.resolve(this.result);
	}
	this.initialized = true;

	return this.promise;
};
Ejemplo n.º 11
0
	init: function () {
		while (this.current < this.length) {
			if (hasOwnProperty.call(this.list, this.current)) break;
			++this.current;
		}
		if (this.current === this.length) {
			if (!this.initialized) {
				throw new Error("Reduce of empty array with no initial value");
			}
			return this.resolve ? this.resolve(this.value) : resolve(this.value);
		}
		if (!this.promise) assign(this, deferred());
		this.processCb = this.processCb.bind(this);
		this.processValue = this.processValue.bind(this);
		this.continue();
		return this.promise;
	},
Ejemplo n.º 12
0
module.exports = function (isRoot, path/*, options*/) {
	var findRoot, options;
	options = arguments[2];
	findRoot = new FindRoot();
	findRoot.isRoot = isRoot;
	findRoot.path = path;
	findRoot.onvalue = findRoot.onvalue.bind(findRoot);
	findRoot.onevent = findRoot.onevent.bind(findRoot);
	assign(findRoot, deferred());
	findRoot.watch = options && options.watch;
	if (findRoot.watch) {
		findRoot.promises = {};
		findRoot.promise.close = findRoot.close.bind(findRoot);
	}
	findRoot.next();
	return findRoot.promise;
};
Ejemplo n.º 13
0
Find = function (list, cb, context) {
	this.list = list;
	this.cb = cb;
	this.context = context;
	this.length = toNaturalNumber(list.length);

	while (this.current < this.length) {
		if (this.current in list) {
			assign(this, deferred());
			this.processCb = this.processCb.bind(this);
			this.process();
			return this.promise;
		}
		++this.current;
	}
	return resolve(undefined);
};
Ejemplo n.º 14
0
Some = function (list, cb, context) {
	this.list = list;
	this.cb = cb;
	this.context = context;
	this.length = list.length >>> 0;

	while (this.current < this.length) {
		if (this.current in list) {
			assign(this, deferred());
			this.processCb = this.processCb.bind(this);
			this.processValue = this.processValue.bind(this);
			this.process();
			return this.promise;
		}
		++this.current;
	}
	return resolve(false);
};
Ejemplo n.º 15
0
	init: function () {
		while (this.current < this.length) {
			if (this.current in this.list) {
				if (!this.promise) {
					assign(this, deferred());
				}
				this.processCb = this.processCb.bind(this);
				this.processValue = this.processValue.bind(this);
				this.process();
				return this.promise;
			}
			++this.current;
		}
		if (!this.initialized) {
			throw new Error("Reduce of empty array with no initial value");
		}
		return this.resolve ? this.resolve(this.value) : deferred(this.value);
	},
Ejemplo n.º 16
0
d = module.exports = function (dscr, value/*, options*/) {
	var c, e, w, options, desc;
	if ((arguments.length < 2) || (typeof dscr !== 'string')) {
		options = value;
		value = dscr;
		dscr = null;
	} else {
		options = arguments[2];
	}
	if (dscr == null) {
		c = w = true;
		e = false;
	} else {
		c = contains.call(dscr, 'c');
		e = contains.call(dscr, 'e');
		w = contains.call(dscr, 'w');
	}

	desc = { value: value, configurable: c, enumerable: e, writable: w };
	return !options ? desc : assign(normalizeOpts(options), desc);
};
Ejemplo n.º 17
0
Multiple.prototype = create(Set.prototype, assign({
	constructor: d(Multiple),
	dbKind: d('multiple'),
	_serialize: d(serialize),
	add: d(function (key) {
		var obj = this.object;
		key = obj._validateMultipleAdd_(this.__pSKey__, key);
		obj._multipleAdd_(this.__pSKey__, key, serialize(key));
		return this;
	}),
	clear: d(function () {
		this.object.database._postponed += 1;
		this._validateClear_().forEach(function (sKey) {
			var item = this.__setData__[sKey];
			if (!item.hasOwnProperty('_value_')) return;
			new Event(item, undefined); //jslint: ignore
		}, this);
		this.object.database._postponed -= 1;
	}),
	delete: d(function (key) {
		var obj = this.object;
		key = obj._validateMultipleDelete_(this.__pSKey__, key);
		if (key == null) return false;
		return obj._multipleDelete_(this.__pSKey__, key, serialize(key));
	}),
	entries: d(function () { return new Iterator(this, 'key+value'); }),
	has: d(function (key) {
		var item;
		if (key == null) return false;
		key = this.object._normalize_(this.__pSKey__, key);
		if (key == null) return false;
		item = this.__setData__[this._serialize(key)];
		if (item == null) return false;
		if (typeof item === 'number') return true;
		return Boolean(item._value_);
	}),
	size: d.gs(function () {
		if (this.hasOwnProperty('__size__')) return this.__size__;
		return this.object._getMultipleSize_(this.__pSKey__);
	}),
	values: d(function () { return new Iterator(this); }),
	first: d.gs(setGetFirst),
	last: d.gs(setGetLast),
	copy: d(setCopy),
	every: d(setEvery),
	some: d(setSome),
	$getOwn: d(function (key) {
		key = this._validate_(key);
		return this.object._getOwnMultipleItem_(this.__pSKey__,
			key, this._serialize(key));
	}),
	$get: d(function (key) {
		key = this._validate_(key);
		return this.object._getMultipleItem_(this.__pSKey__,
			this._serialize(key));
	}),
	_get: d(function (key) {
		key = this._validate_(key);
		return this.object._getMultipleItemObservable_(this.__pSKey__,
			this._serialize(key), key);
	}),
	getLastModified: d(function (key) {
		var item;
		if (key == null) return null;
		key = this.object._normalize_(this.__pSKey__, key);
		if (key == null) return null;
		item = this.__setData__[key];
		if (!item) return 0;
		if (typeof item === 'number') return item;
		return item.lastModified;
	}),
	_validateClear_: d(function () {
		var desc, sKeys;
		this.object._assertWritable_(this.__pSKey__);
		desc = this.object._getDescriptor_(this.__pSKey__);
		sKeys = keys(this.__setData__);
		if (desc.required && (this.size === 1) &&
				sKeys.some(isTruthy, this.__setData__)) {
			throw new DbjsError("Property is required. List must not be empty",
				'MULTIPLE_REQUIRED');
		}
		return sKeys;
	}),
	_validate_: d(function (key) {
		var original = key;
		if (key == null) {
			throw new DbjsError(key + " is not a value", 'ITEM_NULL_VALUE');
		}
		key = this.object._normalize_(this.__pSKey__, key);
		if (key == null) {
			throw new DbjsError(original + " is an invalid value", 'INVALID_VALUE');
		}
		return key;
	}),
	toString: d(toString)
}, lazy({
	_dynamicListeners_: d(function () { return []; },
		{ cacheName: '__dynamicListeners__', desc: '' })
})));
Ejemplo n.º 18
0
Select.prototype = Object.create(DOMSelect.prototype, assign({
	constructor: d(Select)
}, memoizeMethods({
	createOption: d(function (obj) {
		var value;
		if (this.getOptionLabel) {
			value = this.getOptionLabel(obj);
			if (isObservable(value)) value = value.toDOM(this.document);
		} else if (this.property) {
			value = obj._get(this.property);
			if (isObservable(value)) value = value.toDOM(this.document);
		} else {
			value = this.document.createTextNode(obj);
		}
		return createOption.call(this, obj.__id__, value);
	}, { normalizer: getId }),
	createOptgroup: d(function (obj) {
		var el = this.document.createElement('optgroup'), value;
		if (this.group.labelPropertyName) {
			value = obj._get(this.group.labelPropertyName);
			if (isObservable(value)) value = value.toDOMAttr(el, 'label');
			else el.setAttribute('label', value);
		} else {
			el.setAttribute('label', value);
		}
		return el;
	}, { normalizer: getId })
}), autoBind({
	reload: d(function () {
		var els, done, options = this.dbOptions;
		if (this.group) {
			els = [];
			done = create(null);
			options.forEach(function (obj) {
				var group = obj[this.group.propertyName], optgroup, option;
				if (!group) {
					console.warn("No group found for", obj.__id__, "searched by", this.group.propertyName);
					return;
				}
				optgroup = this.createOptgroup(group);
				option = this.createOption(obj);
				if (!done[group.__id__]) {
					clear.call(optgroup);
					done[group.__id__] = true;
					els.push(optgroup);
				}
				optgroup.appendChild(option);
			}, this);
		} else {
			els = options;
		}
		replaceContent.call(this.control, this.chooseOption, els);
	})
})));
Ejemplo n.º 19
0
		toDOMInputComponent: d(function (document/*, options*/) {
			var options = normalizeOptions(arguments[1]), input, inputOptions, dom, cb
			  , db = this.database;

			inputOptions = filter(options, function (value, name) {
				if (name === 'render') return false;
				return !htmlAttributes[name];
			});
			if (options.input) {
				assign(inputOptions, options.input);
				delete inputOptions.input;
			}
			input = this.toDOMInput(document, inputOptions);

			dom = (options.render || componentRender)(input, options);
			if (!dom._dbjsInput) dom._dbjsInput = input;
			forEach(options, function (value, name) {
				if (htmlAttributes[name]) castAttribute.call(dom, name, value);
			}, this);

			dom.classList.add('dbjs-input-component');

			// Required
			dom.classList[options.required ? 'add' : 'remove']('dbjs-required');
			dom.classList[options.required ? 'remove' : 'add']('dbjs-optional');

			// Changed
			input.on('change:changed', cb = function (value) {
				dom.classList[value ? 'add' : 'remove']('changed');
				dom.classList[value ? 'remove' : 'add']('not-changed');
			});
			cb(input.changed);

			// Valid
			input.on('change:valid', cb = function (value) {
				dom.classList[value ? 'add' : 'remove']('valid');
				dom.classList[value ? 'remove' : 'add']('invalid');
			});
			cb(input.valid);

			dom.classList.add('dbjs-not-own');
			// DBJS valid/invalid & empty/filled
			this.on('change', cb = function () {
				var isInvalid, value, isEmpty;
				if (options.required) {
					if (this.value == null) {
						isInvalid = true;
					} else if (db.File && (this.value instanceof db.File) && isNestedObject(this.value)) {
						isEmpty = isInvalid = !this.value.name;
						this.value._name.once('change', cb);
					} else {
						isInvalid = false;
					}
				} else {
					isInvalid = false;
				}
				dom.classList[isInvalid ? 'add' : 'remove']('dbjs-invalid');
				dom.classList[isInvalid ? 'remove' : 'add']('dbjs-valid');
				value = this.value;
				if (isEmpty == null) {
					if (isSet(value)) isEmpty = !value.size;
					else isEmpty = value == null;
				}
				dom.classList[isEmpty ? 'add' : 'remove']('dbjs-empty');
				dom.classList[isEmpty ? 'remove' : 'add']('dbjs-filled');
			}.bind(this));
			cb();
			if (isSet(this.value)) this.value.on('change', cb);
			input.on('destroy', function (cb) { this.off('change', cb); }.bind(this, cb));
			return { dom: dom, input: input, toDOM: toDOM };
		})
Ejemplo n.º 20
0
  , dispatchEvt = require('dom-ext/html-element/#/dispatch-event-2')
  , DOMInput    = require('./input')
  , eventOpts   = require('../_event-options')

  , getValue = Object.getOwnPropertyDescriptor(DOMInput.prototype, 'value').get
  , Input;

module.exports = Input = function (document, type/*, options*/) {
	DOMInput.apply(this, arguments);
};

Input.prototype = Object.create(DOMInput.prototype, {
	constructor: d(Input),
	_value: d(null),
	valid: d(true),
	controlAttributes: d(assign(copy(DOMInput.prototype.controlAttributes), { required: true })),
	_render: d(function () {
		var input = this.control = this.dom = this.document.createElement('input');
		input.setAttribute('type', 'checkbox');
	}),
	required: d.gs(function () { return this._required; }, function (value) {
		value = Boolean(value);
		if (this._required === value) return;
		this._required = value;
		this.onChange();
		this.emit('change:required', value);
	}),
	inputValue: d.gs(function () {
		return this.control.checked ? this.control.value : null;
	}, function (nu) {
		var old = this.inputValue;
Ejemplo n.º 21
0
	this.dom._dbjsFieldset = this;

	this.reload();
};
Object.defineProperty(Fieldset, 'renderRow', d(renderRow));

Object.defineProperties(Fieldset.prototype, assign({
	render: d(function () {
		var el = makeElement.bind(this.document);
		this.dom = el('fieldset', el('table',
			this.domItems = el('tbody')));
	}),
	renderItem: d(function (observable) {
		var options = this.getOptions(observable.ownDescriptor);
		if (options.render == null) options.render = renderRow;
		else if (options.render === 'span') options.render = renderRowSpan;
		return (this.items[observable.dbId] =
			observable.toDOMInputComponent(this.document, options));
	}),
	toDOM: d(function () { return this.dom; }),
	getOptions: d(DOMComposite.prototype.getOptions)
}, autoBind({
	reload: d(function () {
		replaceContent.call(this.domItems, this.prepend, this.list, this.append);
	})
})));

module.exports = exports = memoize(function (db) {
	var proto = setup(db).Base.prototype;

	defineProperty(db.Base, 'DOMFieldset', d(Fieldset));
Ejemplo n.º 22
0
ee(Object.defineProperties(Input.prototype, assign({
	_value: d(''),
	_name: d(''),
	_resolveDbAttributes: d(function (options) {
		if (this._dbAttributesResolved) return;
		options.dbOptions = Object(options.dbOptions);
		forEach(this.dbAttributes, function (name, dbName) {
			var value;
			if (!name) return;
			if (name === true) name = dbName;
			if (options[name] != null) return;
			if (options.dbOptions[dbName] != null) {
				value = options.dbOptions[dbName];
			} else if (this.type[dbName] != null) {
				value = this.type[dbName];
			} else {
				if (dbName === 'required') return;
				if (this.type[dbName] != null) value = this.type[dbName];
				else return;
			}
			options[name] = value;
		}, this);
		defineProperty(this, '_dbAttributesResolved', d(true));
	}),
	controlAttributes: d({ autofocus: true, disabled: true, tabindex: true }),
	dbAttributes: d({}),
	changed: d(false),
	_required: d(false),
	valid: d(false),
	_render: d(function () {
		this.control = this.dom = this.document.createElement('input');
	}),
	name: d.gs(function () {
		return this._name ? (this._name + this._indexString) : '';
	}, function (name) {
		this._name = name;
		name = this.name;
		if (name) this.control.setAttribute('name', name);
		else this.control.removeAttribute('name');
	}),
	_index: d(null),
	_indexString: d.gs(function () {
		return (this._index == null) ? '' : '[' + ((this._index === true) ? '' : this._index) + ']';
	}),
	index: d.gs(function () { return this._index; }, function (index) {
		if (index == null) index = null;
		else if (index !== true) index = (index >>> 0);
		if (index === this._index) return;
		this._index = index;
		this.name = this._name;
	}),
	required: d.gs(function () { return this._required; }, function (value) {
		value = Boolean(value);
		if (this._required === value) return;
		this._required = value;
		this.castControlAttribute('required', value);
		this.onChange();
		this.emit('change:required', value);
	}),
	toDOM: d(function () { return this.dom; }),
	inputValue: d.gs(function () {
		return this.control.value;
	}, function (nu) {
		var old = this.inputValue;
		if (this._value !== nu) {
			this.control.setAttribute('value', this._value = nu);
		}
		if (nu !== old) {
			this.control.value = nu;
			try {
				dispatchEvt.call(this.control, 'change', eventOpts);
			} catch (ignore) {}
		} else {
			this.onChange();
		}
	}),
	value: d.gs(function () {
		return this.type.fromInputValue(this.inputValue);
	}, function (value) {
		value = this.type.toInputValue(value);
		if (value == null) value = '';
		this.inputValue = value;
	}),
	castControlAttribute: d(function (name, value) {
		if (name === 'class') {
			mergeClass.call(this.control, value);
		} else if (!this.controlAttributes[name] && !htmlAttrs[name] &&
				!startsWith.call(name, 'data-')) {
			return;
		}
		if (isRegExp(value)) value = value.source.slice(1, -1);
		castAttr.call(this.control, name, value);
	}),
	destroy: d(function () {
		if (this.form) this.form.removeEventListener('reset', this._onReset, false);
		this.emit('destroy');
	}),
	onChange: d(function () {
		var value, inputValue, changed, valid, emitChanged, emitValid, control, isRequired;
		control = this.control || (this.controls ? this.controls[Object.keys(this.controls)[0]] : null);
		if (control) {
			if (control.form) {
				if (this.form !== control.form) {
					if (this.form) this.form.removeEventListener('reset', this._onReset, false);
					this.form = control.form;
					this.form.addEventListener('reset', this._onReset, false);
				}
			}
		}
		inputValue = this.inputValue;
		value = this.value;
		changed = (inputValue !== this._value);
		if (value != null) {
			valid = this.type.is(value, this.observable && this.observable.descriptor);
		} else {
			if (this.required) isRequired = true;
			else if (this.observable) isRequired = this.observable.descriptor.required;
			if (isRequired) valid = false;
			else valid = ((inputValue == null) || !inputValue.trim());
		}

		if (this.changed !== changed) {
			this.changed = changed;
			emitChanged = true;
		}
		if (this.valid !== valid) {
			this.valid = valid;
			emitValid = true;
		}

		this.emit('change', value);
		if (emitChanged) this.emit('change:changed', this.changed);
		if (emitValid) this.emit('change:valid', this.valid);
	})
}, autoBind({
	_onReset: d(function (e) { this.inputValue = this._value; })
}))));
Ejemplo n.º 23
0
defineProperties(Iterator.prototype, assign({
	constructor: d(Iterator),
	_next: d(function () {
		var i;
		if (!this.__list__) return;
		if (this.__redo__) {
			i = this.__redo__.shift();
			if (i !== undefined) return i;
		}
		if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++;
		this._unBind();
	}),
	next: d(function () { return this._createResult(this._next()); }),
	_createResult: d(function (i) {
		if (i === undefined) return { done: true, value: undefined };
		return { done: false, value: this._resolve(i) };
	}),
	_resolve: d(function (i) { return this.__list__[i]; }),
	_unBind: d(function () {
		this.__list__ = null;
		delete this.__redo__;
		if (!this.__context__) return;
		this.__context__.off('_add', this._onAdd);
		this.__context__.off('_delete', this._onDelete);
		this.__context__.off('_clear', this._onClear);
		this.__context__ = null;
	}),
	toString: d(function () { return '[object Iterator]'; })
}, autoBind({
	_onAdd: d(function (index) {
		if (index >= this.__nextIndex__) return;
		++this.__nextIndex__;
		if (!this.__redo__) {
			defineProperty(this, '__redo__', d('c', [index]));
			return;
		}
		this.__redo__.forEach(function (redo, i) {
			if (redo >= index) this.__redo__[i] = ++redo;
		}, this);
		this.__redo__.push(index);
	}),
	_onDelete: d(function (index) {
		var i;
		if (index >= this.__nextIndex__) return;
		--this.__nextIndex__;
		if (!this.__redo__) return;
		i = this.__redo__.indexOf(index);
		if (i !== -1) this.__redo__.splice(i, 1);
		this.__redo__.forEach(function (redo, i) {
			if (redo > index) this.__redo__[i] = --redo;
		}, this);
	}),
	_onClear: d(function () {
		if (this.__redo__) clear.call(this.__redo__);
		this.__nextIndex__ = 0;
	})
})));
Ejemplo n.º 24
0
Archivo: base.js Proyecto: dlpc/domjs
Object.defineProperties(Base.prototype, assign({
	collect: d(function (fn) {
		var previous = this._current
		  , current = (this._current = this.document.createDocumentFragment());
		fn();
		this._current = previous;
		return current;
	}),
	safeCollect: d(function (fn) { return normalize.call(this.document, this.safeCollectRaw(fn)); }),
	safeCollectRaw: d(function (fn) {
		var direct, result;
		result = this.collect(function () { direct = fn(); });
		return normalizeRaw.call(this.document, (direct === undefined) ? result : direct);
	})
}, lazy({
	_commentProto: d(function self() {
		var proto = create(getPrototypeOf(this.document.createComment('')), {
			domjs: d(this)
		});
		forEach(ext._comment, function (value, name) {
			defineProperty(proto, name, d(value));
		});
		return proto;
	}),
	_textProto: d(function () {
		var proto = create(getPrototypeOf(this.document.createTextNode('')), {
			domjs: d(this)
		});
		forEach(ext._text, function (value, name) {
			defineProperty(proto, name, d(value));
		});
		return proto;
	})
}), memoizeMethods({
	_elementProto: d(function (name) {
		var proto = create(getPrototypeOf(this.document.createElement(name)));
		forEach(ext._element, function (value, name) {
			defineProperty(proto, name, d(value));
		});
		if (ext[name]) {
			forEach(ext[name], function (value, name) {
				defineProperty(proto, name, d(value));
			});
		}
		defineProperties(proto, {
			domjs: d(this),
			_directives: d(this.getDirectives(name))
		});
		return proto;
	}),
	getDirectives: d(function (name) {
		return (this._directives[name] = create(this._directives._element));
	})
}), {
	ns: d(create(null, autoBind({
		comment: d('cew', function (data) {
			var el = this._current.appendChild(this.document.createComment(data));
			el.__proto__ = this._commentProto;
			if (el._construct) el._construct.apply(el, slice.call(arguments, 1));
			return el;
		}),
		text: d('cew', function (data/* …data*/) {
			var el = this._current.appendChild(this.document.createTextNode(data));
			el.__proto__ = this._textProto;
			if (el._construct) el._construct.apply(el, slice.call(arguments, 1));
			return el;
		}),
		element: d('cew', function (name/*[, attributes], …content*/) {
			var el = this._current.appendChild(this.document.createElement(name));
			el.__proto__ = this._elementProto(name);
			construct(el, slice.call(arguments, 1));
			return el;
		}),
		normalize: d('cew', function (node) {
			var name = validNode(node).nodeName.toLowerCase();
			if (name === '#text') node.__proto__ = this._textProto;
			else if (name === '#comment') node.__proto__ = this._commentProto;
			else if (name[0] !== '#') node.__proto__ = this._elementProto(name);
			else throw new TypeError("Unsupported node type");
			return node;
		}),
		insert: d('cew', function (node/*, …nodes*/) {
			var dom = normalize.apply(this.document, arguments);
			if (isArray(dom)) dom.forEach(this._current.appendChild, this._current);
			else if (dom != null) this._current.appendChild(dom);
			return dom;
		})
	}, '_domjs')))
}));
Ejemplo n.º 25
0
if( setPrototypeOf ) setPrototypeOf( PrimitiveSetIterator, Iterator );

PrimitiveSetIterator.prototype = Object.create( Iterator.prototype, assign( {
	constructor: d( PrimitiveSetIterator ),
	_resolve: d( function( i ) {
		var value = this.__data__[this.__list__[i]];
		return (this.__kind__ === 'value') ? value : [value, value];
	} ),
	_unBind: d( function() {
		this.__data__ = null;
		unBind.call( this );
	} ),
	toString: d( function() {
		return '[object Set Iterator]';
	} )
}, autoBind( {
	_onAdd: d( function( key ) {
		this.__list__.push( key );
	} ),
	_onDelete: d( function( key ) {
		var index = this.__list__.lastIndexOf( key );
		if( index < this.__nextIndex__ ) return;
		this.__list__.splice( index, 1 );
	} ),
	_onClear: d( function() {
		clear.call( this.__list__ );
		this.__nextIndex__ = 0;
	} )
} ) ) );
Object.defineProperty( PrimitiveSetIterator.prototype, toStringTagSymbol,
	d( 'c', 'Set Iterator' ) );
Ejemplo n.º 26
0
Input.prototype = Object.create(DOMInput.prototype, assign({
	constructor: d(Input),
	multiple: d(false),
	_value: d(null),
	controlAttributes: d(assign(copy(DOMInput.prototype.controlAttributes),
		{ required: true })),
	dbAttributes: d(assign(copy(DOMInput.prototype.dbAttributes),
		{ required: true })),
	_render: d(function (options) {
		this.dom = (options.render || render).call(this, options);
		this.controls.push(this.control);
	}),
	name: d.gs(getName, function (name) {
		this._name = name;
		name = this.name;
		this.controls.forEach(function (input) { input.name = name; });
	}),
	inputValue: d.gs(function () {
		var value, item;
		if (!this.multiple) {
			if (this.control.files && this.control.files[0]) return this.control.files[0];
			item = this.valueDOM.firstElementChild;
			if (!item) return null;
			if (item.classList.contains('empty')) return null;
			if (item.querySelector('input[type=checkbox]').checked) return null;
			return this.valueDOM.firstElementChild.getAttribute('data-id');
		}
		value = compact.call(map.call(this.valueDOM.childNodes, function (item) {
			var id;
			if (item.classList.contains('empty')) return null;
			if (item.querySelector('input[type=checkbox]').checked) return null;
			id = item.getAttribute('data-id');
			if (!id) throw new TypeError("Missing id (data-id attribute) on file item");
			return id;
		})).concat(this.control.files ? aFrom(this.control.files) : []);
		return value.length ? value : null;
	}, function (nu) {
		var old = this.inputValue, changed;
		this._value = nu;
		if (this.multiple) {
			if (nu) {
				replaceCont.call(this.valueDOM,
					nu.sort(byNameLastModified.bind(this.type)).map(this._renderItem));
				if (this._required) this.castControlAttribute('required', false);
				changed = true;
				this.dom.classList.add('filled');
				this.control.value = null;
			} else {
				this.control.value = null;
				clear.call(this.valueDOM);
				if (this._required) this.castControlAttribute('required', true);
				this.dom.classList.remove('filled');
			}
		} else if (nu !== old) {
			this.control.value = null;
			if (nu) {
				replaceCont.call(this.valueDOM, this._renderItem(nu));
				this.dom.classList.add('filled');
			} else {
				clear.call(this.valueDOM);
				this.dom.classList.remove('filled');
			}
			changed = true;
		}
		if (changed) {
			try {
				dispatchEvnt.call(this.control, 'change', eventOpts);
			} catch (ignore) {}
		} else {
			this.onChange();
		}
		this.updateRequired();
	}),
	value: d.gs(function () {
		var value = this.inputValue;
		if (value == null) return null;
		if (this.multiple) return value.map(this.type.toInputValue, this.type);
		return this.type.toInputValue(value);
	}, function (value) {
		if (value == null) {
			value = null;
		} else if (this.multiple) {
			if (isMap(value)) value = toArray(value).map(getMapValue).filter(filterEmpty);
			else value = toArray(value);
			if (value.length) {
				value = compact.call(value.map(this.type.toInputValue, this.type));
			}
			if (!value.length) value = null;
		} else {
			if (this.observable.descriptor.nested) value._name.on('change', this.onChange);
			value = this.type.toInputValue(value);
		}

		this.inputValue = value;
	}),
	updateRequired: d(function () {
		if (!this._required) return;
		this.castControlAttribute('required',
			aFrom(this.valueDOM.querySelectorAll('input[type=checkbox]')).every(function (input) {
				return input.checked;
			}));
	}),
	onChange: d(function () {
		var value, changed, valid, emitChanged, emitValid, isRequired;
		if (this.control.form) {
			if (this.form !== this.control.form) {
				if (this.form) this.form.removeEventListener('reset', this._onReset, false);
				this.form = this.control.form;
				this.form.addEventListener('reset', this._onReset, false);
			}
		}
		value = this.inputValue;
		changed = aFrom(this.valueDOM.querySelectorAll('input[type=checkbox]')).some(function (input) {
			return input.checked;
		});
		changed = (this.multiple && (this._value != null) && (value != null))
			? isCopy.call(value, this._value) : (value !== this._value);
		if (this.required) isRequired = true;
		else if (this.observable) isRequired = this.observable.descriptor.required;
		valid = isRequired ? (value != null) : true;

		if (this.changed !== changed) {
			this.changed = changed;
			emitChanged = true;
		}
		if (this.valid !== valid) {
			this.valid = valid;
			emitValid = true;
		}
		this.updateRequired();
		this.emit('change', value);
		if (emitChanged) this.emit('change:changed', this.changed);
		if (emitValid) this.emit('change:valid', this.valid);
	}),
	removeItem: d(function (dom) {
		remove.call(dom);
		if (!this.multiple) this.dom.classList.remove('filled');
		dispatchEvnt.call(this.control, 'change', eventOpts);
	})
}, autoBind({
	_onReset: d(function () {
		this.control.value = null;
		if (this.control.files && this.control.files.length) {
			// In Opera control is not reset properly, force it with hack
			getForceReset(this.document)(this.control);
		}
		aFrom(this.valueDOM.querySelectorAll('input[type=checkbox]')).every(function (input) {
			input.checked = false;
		});
		this.onChange();
	})
}), memoizeMethods({
	_renderItem: d(function (file) {
		var data;
		file = this.type.getById(file);
		data = this.renderItem(file);
		if (data.control) this.controls.push(data.control);
		return data.dom;
	})
})));
Ejemplo n.º 27
0
Object.defineProperties(DOM.prototype, assign({
	update: d(function () {
		var parent, value = this.observable.value
		  , dom = (value != null) ? this.render(value) : this.location;
		if (dom === this.current) return;
		if (isArray(this.current)) {
			this.current.forEach(function (node) { remove.call(node); });
		} else if ((this.current != null) && (this.current !== this.location)) {
			remove.call(this.current);
		}
		this.current = dom;
		if (dom === this.location) return;
		if (dom == null) return;
		parent = this.location.parentNode;
		if (isArray(dom)) {
			dom.forEach(function (node) {
				parent.insertBefore(node, this.location);
			}, this);
		} else {
			parent.insertBefore(dom, this.location);
		}
	}),
	toDOM: d(function () {
		var df;
		if ((this.current == null) || (this.current === this.location)) {
			return this.current;
		}
		df = this.document.createDocumentFragment();
		if (isArray(this.current)) this.current.forEach(df.appendChild, df);
		else df.appendChild(this.current);
		df.appendChild(this.location);
		return df;
	})
}, memoizeMethods({
	render: d(function (value) { return this.cb(value); },
		{ getNormalizer: require('memoizee/normalizers/get-1') })
})));
Ejemplo n.º 28
0
Archivo: index.js Proyecto: dlpc/domjs
			el.__proto__ = proto;
		} catch (e) {
			// Workaround for FF bug ->
			// https://bugzilla.mozilla.org/show_bug.cgi?id=913420
			mixin(el, proto);
		}
		construct(el, arguments);
		return el;
	});
});
elements._var = elements.var;

module.exports = HTML5 = function (document) {
	if (!(this instanceof HTML5)) return new HTML5(document);
	Base.call(this, validDocument(document));
};

HTML5.prototype = Object.create(Base.prototype, {
	constructor: d(HTML5),
	ns: d(Object.create(Base.prototype.ns, autoBind(elements, '_domjs')))
});

assign(require('./ext'), {
	ol:       require('./ext/html5/ol'),
	optgroup: require('./ext/html5/optgroup'),
	script:   require('./ext/html5/script'),
	select:   require('./ext/html5/select'),
	tbody:    require('./ext/html5/tbody'),
	ul:       require('./ext/html5/ul')
});
Ejemplo n.º 29
0
Object.defineProperties(SyncMaster.prototype, assign({
	initialized: d(false),
	initialize: d(function () {
		this.initialized = true;
		this.syncProperties(this.object);
		this.object.on('update', this.onDbEvent);
	}),
	syncProperties: d(function (object) {
		var sKey, desc, observable, event;

		for (sKey in object.__descriptors__) {
			desc = object.__descriptors__[sKey];
			if (desc.reverse != null) continue;
			if (desc.nested) {
				if (object.hasOwnProperty('__objects__') && object.__objects__[desc._sKey_]) {
					this.syncProperties(object.__objects__[desc._sKey_]);
				}
				continue;
			}
			if (!desc[this.base.propertyName]) continue;

			// Export!
			if (!desc._resolveValueGetter_()) {

				// Static
				this.namesToSync[object.__id__ + '/' + sKey] = true;
				if (desc.multiple) {
					if (!object.hasOwnProperty('__multiples__')) continue;
					if (!hasOwnProperty.call(object.__multiples__, sKey)) continue;
					forEach(object.__multiples__[sKey], this.syncObjectDirectly, this);
					continue;
				}
				if (desc.object !== object) continue;
				this.syncObjectDirectly(desc);
				continue;
			}

			// Computable
			if (desc.multiple) {
				this.observed.push(observable = object._get_(sKey));
				event = object._getPropertyLastEvent_(sKey);
				this.groundComputedSet(observable, event);
				this.syncComputedSet(observable, resolveTargetValue(this.base.db, object.__id__, sKey),
					event);
				observable.on('change', this.onSetChangeEvent);
				continue;
			}
			this.observed.push(observable = object._getObservable_(sKey));
			this.syncComputedValue(observable, object._getPropertyLastEvent_(sKey));
			observable.on('change', this.onChangeEvent);
		}
	}),
	syncObjectDirectly: d(function (object) {
		var event = object._lastOwnEvent_;
		if (!event) return;
		this.syncEventDirectly(event);
	}),
	syncExternal: d(function (path, object, isMultiple, multipleValue) {
		var id, prevId;
		object = object.master;
		if (object === this.object) return;
		if (typeof object === 'function') return;
		if (object._kind_ !== 'object') return;
		if (object.constructor.prototype === object) return;
		id = object.__id__;
		if (isMultiple) {
			if (multipleValue) {
				if (!this.extValuesMap[path]) this.extValuesMap[path] = create(null);
				if (this.extValuesMap[path][id]) return;
				this.extValuesMap[path][id] = true;
				if (!this.descendants[id]) {
					this.descendants[id] = 0;
					this.base._syncMaster(object);
				}
				++this.descendants[id];
				return;
			}
			if (!this.extValuesMap[path]) return;
			if (!this.extValuesMap[path][id]) return;
			delete this.extValuesMap[path][id];
			if (!--this.descendants[id]) this.base._unsyncMaster(object);
			return;
		}
		prevId = this.extValuesMap[path];
		if (prevId && (!--this.descendants[prevId])) {
			this.base._unsyncMaster(object.database.objects.getById(prevId));
		}
		this.extValuesMap[path] = id;
		if (!this.descendants[id]) {
			this.descendants[id] = 0;
			this.base._syncMaster(object);
		}
		++this.descendants[id];
	}),
	syncEventDirectly: d(function (event) {
		var value = event.value, object = event.object, targetEvent, constructor;
		if (object._kind_ === 'descriptor') {
			if (value && value.hasOwnProperty('__id__')) {
				this.syncExternal(object.__valueId__, value);
				value = this.base.db.objects.getById(value.__id__);
			}
		} else if (object._kind_ === 'item') {
			if (object.key.hasOwnProperty('__id__')) {
				this.syncExternal(object.object.__id__ + '/' + object._pSKey_, object.key, true, value);
			}
		} else if (object._kind_ === 'object') {
			if (value && value.hasOwnProperty('__id__')) {
				value = this.base.db.objects.getById(value.__id__);
				if (value.constructor.prototype === value) constructor = value.constructor;
			}
		}
		object = this.base.db.objects.unserialize(event.object.__valueId__, constructor);
		targetEvent = object._lastOwnEvent_;
		if (targetEvent && (targetEvent.stamp >= event.stamp)) return;
		new DbjsEvent(object, value, event.stamp, event.sourceId, event.index); //jslint: ignore
	}),
	syncComputedValue: d(function (observable, event) {
		var source = observable.value
		  , targetObject = resolveTargetObject(this.base.db, observable.object.__id__)
		  , target = targetObject._get_(observable.__sKey__)
		  , stamp, targetLastEvent;
		if (source === target) return;
		if (source && source.hasOwnProperty('__id__')) this.syncExternal(observable.dbId, source);
		stamp = (event && event.stamp) || 0;
		targetLastEvent = targetObject._getOwnDescriptor_(observable.__sKey__)._lastOwnEvent_;
		if (targetLastEvent && (targetLastEvent.stamp >= stamp)) stamp = targetLastEvent.stamp + 1;
		new DbjsEvent(targetObject._getOwnDescriptor_(observable.__sKey__),
			source, stamp, event && event.sourceId); //jslint: ignore
		target = targetObject._get_(observable.__sKey__);
		if (source == null) {
			if (target == null) return;
		} else if (typeof source === typeof target) {
			return;
		}
		throw new Error("Database reduction error:\n" +
			"\tComputed value (" + observable.dbId + ") in result database after propagation didn't " +
			"match one in source\n" +
			"\tMost likely it's caused by model not being completely tagged for propagation\n" +
			"\t(type of propagated value doesn't match defined type)");
	}),
	groundComputedSet: d(function (observable, event) {
		var targetObject = resolveTargetObject(this.base.db, observable.object.__id__)
		  , stamp, targetLastEvent, desc;
		stamp = (event && event.stamp) || 0;
		desc = targetObject._getOwnDescriptor_(observable.__sKey__);
		targetLastEvent = desc._lastOwnEvent_;
		if (targetLastEvent && (targetLastEvent.stamp >= stamp)) stamp = targetLastEvent.stamp + 1;
		new DbjsEvent(desc, null, stamp, event && event.sourceId); //jslint: ignore
	}),
	syncComputedSet: d(function (source, target, event) {
		var sourceIterator, targetIterator, item, isDifferent, stamp, sourceKeys, targetKeys;

		if (source.size === target.size) {
			if (!source.size) return;
			sourceIterator = source.values();
			targetIterator = target.values();
			item = sourceIterator.next();
			while (!item.done) {
				if (item.value !== targetIterator.next().value) {
					isDifferent = true;
					break;
				}
				item = sourceIterator.next();
			}
			if (sourceIterator._destroy) sourceIterator._destroy();
			if (targetIterator._destroy) targetIterator._destroy();
			if (!isDifferent) return;
		}
		stamp = (event && event.stamp) || 0;
		forEach(target.__setData__, function (item) {
			var event = item._lastOwnEvent_;
			if (!event) return;
			if (event.stamp >= stamp) stamp = event.stamp + 1;
		});
		target.forEach(function (item) {
			var sObj;
			if (!source.has(item)) {
				if (item.hasOwnProperty('__id__')) {
					sObj = source.object.database.objects.getById(item.__id__);
					if (!sObj) {
						throw new TypeError("Could not find '" + item.__id__ + "' object in source database");
					}
					this.syncExternal(target.dbId, sObj, true, undefined);
				}
				propagateComputedItem.call(this, stamp++, target.dbId, undefined, item);
			}
		}, this);
		source.forEach(function (item) {
			if (item.hasOwnProperty('__id__')) this.syncExternal(target.dbId, item, true, true);
			propagateComputedItem.call(this, stamp++, target.dbId, true, item);
		}, this);
		if (source.size !== target.size) {
			sourceKeys = [];
			targetKeys = [];
			source.forEach(function (item) { sourceKeys.push(serializeKey(item)); });
			target.forEach(function (item) { targetKeys.push(serializeKey(item)); });
			throw new Error("Database reduction error:\n" +
				"\tComputed set (" + source.dbId + ") of size \"" + target.size +
				"\" in result database after propagation didn't match one in source (size: \"" +
				source.size + "\"\n" +
				"\tKeys not found in target: " + diff.call(sourceKeys, targetKeys) + "\n" +
				"\tMost likely it's caused by model not being completely tagged for propagation\n" +
				"\t(type of propagated set values doesn't match defined type)");
		}
	}),
	destroy: d(function () {
		this.object.off('update', this.onDbEvent);
		this.observed.forEach(function (observable) {
			observable.off('change', isSet(observable) ? this.onSetChangeEvent : this.onChangeEvent);
		}, this);
		clear.call(this.observed);
		this.initialized = false;
	}),
	remove: d(function () {
		this.destroy();
		delete this.base.map[this.object.__id__];
		delete this.base.masterMap[this.object.__id__];
		this.object.off('turn', this.onTurn);
	})
}, autoBind({
	onTurn: d(function (event) {
		this.syncEventDirectly(event);
		if (this.object.constructor.__id__ === 'Base') {
			if (!this.initialized) return;
			this.destroy();
			return;
		}
		if (this.initialized) return;
		this.initialize();
	}),
	onDbEvent: d(function (event) {
		var object = event.object;
		switch (object._kind_) {
		case 'descriptor':
			if (!this.namesToSync[object.__valueId__]) return;
			break;
		case 'item':
			if (!this.namesToSync[object.object.__id__ + '/' + object._pSKey_]) return;
			break;
		case 'object':
			return;
		case 'sub-descriptor':
			return;
		}
		this.syncEventDirectly(event);
	}),
	onChangeEvent: d(function (event) { this.syncComputedValue(event.target, event.dbjs); }),
	onSetChangeEvent: d(function (event) {
		this.syncComputedSet(event.target, resolveTargetValue(this.base.db,
			event.target.object.__id__, event.target.__sKey__), event.dbjs);
	})
})));
Ejemplo n.º 30
0
defineProperties(Driver.prototype, assign({
	destroy: d(function () {
		this.__main__.sets.delete(this.__fragment__);
		this.__fragment__.off('update', this.onUpdate);
		this.__object__._assignments_.off('change', this.onAssignChange);
		this.extend.clear();
		this.__fragment__.destroy();
	}),
	onAssign: d(function (dbObj) {
		var rules, args, sKey;
		if (this.__path__[dbObj.master.__id__]) return;
		rules = this.__rules__.assignment;
		if (!rules) return;
		if (dbObj._kind_ === 'descriptor') sKey = dbObj._sKey_;
		else sKey = dbObj._pSKey_;
		rules = pass(this.__object__, dbObj.object, sKey, rules);
		if (!rules) return;
		args = [dbObj.master, rules.property, rules.value, rules.assignment];
		this.__values__[dbObj.__id__] = { args: args };
		this.extend.apply(this, args);
	}),
	onDismiss: d(function (dbObj) {
		var data = this.__values__[dbObj.__id__];
		if (!data) return;
		this.extend.deleteRef.apply(this, data.args);
		delete this.__values__[dbObj.__id__];
	})
}, memoizeMethods({
	extend: d(function (object, rProperty, rValue, rAssignment) {
		return new Driver(this.__main__, object, this.__path__,
			{ property: rProperty, value: rValue, assignment: rAssignment });
	}, { getNormalizer: getNormalizer, refCounter: true,
		dispose: function (driver) { driver.destroy(); } })
}), autoBind({
	onUpdate: d(function (event) {
		var dbObj = event.object, kind = dbObj._kind_, old, value, rules, args
		  , removed, sKey;
		if (kind === 'object') return;
		if (kind === 'sub-descriptor') return;
		if (kind === 'descriptor') {
			value = event.value;
			sKey = dbObj._sKey_;
		} else {
			// Multiple item
			removed = !event.value;
			value = dbObj.key;
			sKey = dbObj._pSKey_;
		}
		old = this.__values__[dbObj.__id__];
		if (old) {
			if (!removed && (value === old.object)) return;
			this.extend.deleteRef.apply(this, old.args);
			delete this.__values__[dbObj.__id__];
		}
		if (removed) return;
		if (!value || !value.__id__ || (value._kind_ !== 'object')) return;
		if (this.__path__[value.master.__id__]) return;
		rules = this.__rules__.value;
		if (!rules) return;
		rules = pass(this.__object__, dbObj.object, sKey, rules);
		if (!rules) return;
		args = [value.master, rules.property, rules.value, rules.assignment];
		this.__values__[dbObj.__id__] = { object: value, args: args };
		this.extend.apply(this, args);
	}),
	onAssignChange: d(function (event) {
		if (event.type === 'add') {
			this.onAssign(event.value);
			return;
		}
		if (event.type === 'delete') {
			this.onDismiss(event.value);
			return;
		}
		if (event.type === 'batch') {
			if (this.added) this.added.forEach(this.onAssign, this);
			if (this.deleted) this.deleted.forEach(this.onDismiss, this);
			return;
		}
		// Must not happen, throw for awareness
		throw new TypeError("Unrecognized event");
	})
})));