Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
102 lines
2.7 KiB
JavaScript
Executable file
102 lines
2.7 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
define(function() {
|
|
function unobserve(_eventHandlers, prop, handler) {
|
|
// arguments in reverse order to support .bind(handler) for the
|
|
// unbind from all case
|
|
function removeHandler(handler, prop) {
|
|
var handlers = _eventHandlers[prop];
|
|
if (!handlers) {
|
|
return;
|
|
}
|
|
var index = handlers.indexOf(handler);
|
|
if (index >= 0) {
|
|
handlers.splice(index, 1);
|
|
}
|
|
}
|
|
|
|
if (typeof prop === 'function') {
|
|
// (handler) -- remove from every key in _eventHandlers
|
|
Object.keys(_eventHandlers).forEach(removeHandler.bind(null, prop));
|
|
} else if (handler) {
|
|
// (prop, handler) -- remove handler from the specific prop
|
|
removeHandler(handler, prop);
|
|
} else if (prop in _eventHandlers) {
|
|
// (prop) -- otherwise remove all handlers for property
|
|
_eventHandlers[prop] = [];
|
|
}
|
|
}
|
|
|
|
/*
|
|
* An Observable is able to notify its property change. It is initialized by
|
|
* an ordinary object.
|
|
*/
|
|
function Observable(obj) {
|
|
var _eventHandlers = {};
|
|
var _observable = {
|
|
observe: function o_observe(p, handler) {
|
|
/*
|
|
* We should check if _observable[_p] exists. Since _observable[_p] is
|
|
* created along with _eventHandlers[p], here we simply check
|
|
* _eventHandlers[p].
|
|
*/
|
|
var handlers = _eventHandlers[p];
|
|
if (handlers) {
|
|
handlers.push(handler);
|
|
}
|
|
},
|
|
/**
|
|
* unobserve([prop], handler) - remove handler from observeable callbacks
|
|
*/
|
|
unobserve: unobserve.bind(null, _eventHandlers)
|
|
};
|
|
|
|
var _getFunctionTemplate = function(p) {
|
|
return function() {
|
|
return _observable['_' + p];
|
|
};
|
|
};
|
|
|
|
var _setFunctionTemplate = function(p) {
|
|
return function(value) {
|
|
var oldValue = _observable['_' + p];
|
|
if (oldValue !== value) {
|
|
_observable['_' + p] = value;
|
|
var handlers = _eventHandlers[p];
|
|
handlers.forEach(function(handler) {
|
|
handler(value, oldValue);
|
|
});
|
|
}
|
|
};
|
|
};
|
|
|
|
/*
|
|
* Iterate all properties in the object and create corresponding getter and
|
|
* setter for them.
|
|
*/
|
|
for (var p in obj) {
|
|
// If p is a function, simply add it to the observable.
|
|
if (typeof obj[p] === 'function') {
|
|
_observable[p] = obj[p];
|
|
continue;
|
|
}
|
|
|
|
_eventHandlers[p] = [];
|
|
|
|
Object.defineProperty(_observable, '_' + p, {
|
|
value: obj[p],
|
|
writable: true
|
|
});
|
|
|
|
Object.defineProperty(_observable, p, {
|
|
enumerable: true,
|
|
get: _getFunctionTemplate(p),
|
|
set: _setFunctionTemplate(p)
|
|
});
|
|
}
|
|
|
|
return _observable;
|
|
}
|
|
|
|
return Observable;
|
|
});
|