VulpesOS/gaia/apps/calendar/js/service/ical_recur_expansion.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

101 lines
2.6 KiB
JavaScript
Executable file

define(function(require, exports, module) {
'use strict';
var ICAL = require('ext/ical');
module.exports = {
/**
* Maximum iterations must be > 0 && < Infinity.
* Lower values are probably better as we can show progress
* for multiple events rather then complete one long recurring
* event after another...
*/
forEachLimit: 200,
_isDone: function(last, sent, max) {
if (last && max && last.compare(max) >= 0) {
return true;
} else if (sent < this.forEachLimit) {
return false;
}
return true;
},
/**
* Iterates through a recur expansion instance.
* Gracefully handles existing iterators (including failures).
* Will fallback to complete re-expansion when necessary.
*
* NOTE: This method intentionally does not accept the "forEach"
* function as the final argument to indicate it does not follow
* the NodeJS example...
*
* minDate is always exclusive
* maxDate is not strict and may include one occurrence beyond.
*
* @param {ICAL.Event} event complete event.
* @param {Null|Object} iterator or nothing.
* @param {Function} forEach receives [nextDate].
* @param {ICAL.Time|Null} minDate minimum time (defaults to start).
* @param {ICAL.Time|Null} maxDate maximum date (defaults to none).
* @return {ICAL.RecurExpansion} iterator.
*/
forEach: function(event, iterator, each, min, max) {
// if there is no iterator create one...
if (!iterator) {
return this._beginIteration(event, each, min, max);
}
var iter;
try {
iter = this._resumeIteration(event, iterator, each, min, max);
} catch (e) {
console.error('Iteration Error: ' + e.toString());
iter = this._beginIteration(event, each, min, max);
}
return iter;
},
_resumeIteration: function(event, iterator, each, min, max) {
if (!(iterator instanceof ICAL.RecurExpansion)) {
iterator = new ICAL.RecurExpansion(iterator);
}
this._iterate(event, iterator, each, min, max);
return iterator;
},
_beginIteration: function(event, each, min, max) {
var iterator = event.iterator();
this._iterate(event, iterator, each, min, max);
return iterator;
},
_iterate: function(event, iterator, each, min, max) {
// keep track of the iterations
var sent = 0;
var current;
do {
current = iterator.next();
if (!current) {
break;
}
if (!min || current.compare(min) > 0) {
// sent should be inside the loop to guard against
// the possibility that the resume functionality breaking.
sent++;
each(current);
}
} while (!this._isDone(current, sent, max));
}
};
});