| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- 'use strict';
- function dirtyReporter() {
- const dirty = new Map();
- const onchanges = [];
- function add(obj, value) {
- const saved = dirty.get(obj);
- if (!saved) {
- dirty.set(obj, {type: 'add', newValue: value});
- } else if (saved.type === 'remove') {
- if (saved.savedValue === value) {
- dirty.delete(obj);
- } else {
- saved.newValue = value;
- saved.type = 'modify';
- }
- }
- }
- function remove(obj, value) {
- const saved = dirty.get(obj);
- if (!saved) {
- dirty.set(obj, {type: 'remove', savedValue: value});
- } else if (saved.type === 'add') {
- dirty.delete(obj);
- } else if (saved.type === 'modify') {
- saved.type = 'remove';
- }
- }
- function modify(obj, oldValue, newValue) {
- const saved = dirty.get(obj);
- if (!saved) {
- if (oldValue !== newValue) {
- dirty.set(obj, {type: 'modify', savedValue: oldValue, newValue});
- }
- } else if (saved.type === 'modify') {
- if (saved.savedValue === newValue) {
- dirty.delete(obj);
- } else {
- saved.newValue = newValue;
- }
- } else if (saved.type === 'add') {
- saved.newValue = newValue;
- }
- }
- function clear(obj) {
- if (obj === undefined) {
- dirty.clear();
- } else {
- dirty.delete(obj);
- }
- }
- function isDirty() {
- return dirty.size > 0;
- }
- function onChange(cb) {
- // make sure the callback doesn't throw
- onchanges.push(cb);
- }
- function wrap(obj) {
- for (const key of ['add', 'remove', 'modify', 'clear']) {
- obj[key] = trackChange(obj[key]);
- }
- return obj;
- }
- function emitChange() {
- for (const cb of onchanges) {
- cb();
- }
- }
- function trackChange(fn) {
- return function () {
- const dirty = isDirty();
- const result = fn.apply(null, arguments);
- if (dirty !== isDirty()) {
- emitChange();
- }
- return result;
- };
- }
- function has(key) {
- return dirty.has(key);
- }
- return wrap({add, remove, modify, clear, isDirty, onChange, has});
- }
|