VulpesOS/gaia/apps/bluetooth/js/modules/mvvm/observable_array.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

153 lines
3.4 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 ObservableArray is able to notify its change through four basic
* operations including 'insert', 'remove', 'replace', 'reset'. It is
* initialized by an ordinary array.
*/
function ObservableArray(array) {
var _array = array || [];
var _eventHandlers = {
'insert': [],
'remove': [],
'replace': [],
'reset': []
};
var _notify = function(eventType, data) {
var handlers = _eventHandlers[eventType];
handlers.forEach(function(handler) {
handler({
type: eventType,
data: data
});
});
};
return {
get length() {
return _array.length;
},
get array() {
return _array;
},
forEach: function oa_foreach(func) {
_array.forEach(func);
},
observe: function oa_observe(eventType, handler) {
var handlers = _eventHandlers[eventType];
if (handlers) {
handlers.push(handler);
}
},
unobserve: unobserve.bind(null, _eventHandlers),
push: function oa_push(item) {
_array.push(item);
_notify('insert', {
index: _array.length - 1,
count: 1,
items: [item]
});
},
pop: function oa_pop() {
if (!_array.length) {
return;
}
var item = _array.pop();
_notify('remove', {
index: _array.length,
count: 1
});
return item;
},
splice: function oa_splice(index, count) {
if (arguments.length < 2) {
return;
}
var addedItems = Array.prototype.slice.call(arguments, 2);
_array.splice.apply(_array, arguments);
if (count) {
_notify('remove', {
index: index,
count: count
});
}
if (addedItems.length) {
_notify('insert', {
index: index,
count: addedItems.length,
items: addedItems
});
}
},
set: function oa_set(index, value) {
if (index < 0 || index >= _array.length) {
return;
}
var oldValue = _array[index];
_array[index] = value;
_notify('replace', {
index: index,
oldValue: oldValue,
newValue: value
});
},
get: function oa_get(index) {
return _array[index];
},
reset: function oa_reset(array) {
_array = array;
_notify('reset', {
items: _array
});
}
};
}
return ObservableArray;
});