diff options
Diffstat (limited to 'static/recurrence')
-rw-r--r-- | static/recurrence/css/recurrence.css | 294 | ||||
-rw-r--r-- | static/recurrence/img/recurrence-calendar-icon.png | bin | 285 -> 0 bytes | |||
-rw-r--r-- | static/recurrence/js/recurrence-widget.js | 1795 | ||||
-rw-r--r-- | static/recurrence/js/recurrence.js | 1105 |
4 files changed, 0 insertions, 3194 deletions
diff --git a/static/recurrence/css/recurrence.css b/static/recurrence/css/recurrence.css deleted file mode 100644 index ea3a4fd..0000000 --- a/static/recurrence/css/recurrence.css +++ /dev/null @@ -1,294 +0,0 @@ -div.recurrence-widget { - float: left; - border: 1px solid #ccc; -} - -div.recurrence-widget div.panel { - border-bottom: 1px solid #ddd; -} - -div.recurrence-widget select, -div.recurrence-widget input { - margin: 0 .5em; -} - -div.recurrence-widget a.recurrence-label { - display: block; - cursor: pointer; - padding: .5em .75em; - font-weight: bold; - white-space: nowrap; - padding-right: 3em; - color: black; -} - -div.recurrence-widget .remove, -div.recurrence-widget .remove:link, -div.recurrence-widget .remove:visited { - float: left; - padding: .25em .5em; - font-size: 1.1em; - font-weight: bold; - cursor: pointer; - text-decoration: none; - color: #555; - line-height: 1.4em; -} - -div.recurrence-widget .remove:hover { - color: #a00; -} - -div.recurrence-widget .control { - padding: .5em 1em .5em .5em; -} - -div.recurrence-widget .add-button, -div.recurrence-widget .add-button:link, -div.recurrence-widget .add-button:visited { - color: green; -} - -div.recurrence-widget .plus { - font-size: 1.2em; - font-weight: bold; - padding-right: .5em; -} - -div.recurrence-widget .add-button:hover { - color: green; -} - -div.recurrence-widget .control .add-date { - padding-left: 1em; - margin-left: 1em; - border-left: 1px solid #ddd; -} - -div.recurrence-widget .freq { - display: inline -} - -div.recurrence-widget .interval { - display: inline; - padding-left: 1em; -} - -div.recurrence-widget form { - overflow: hidden; - padding: .5em 2.2em; - border-top: 1px solid #ddd; -} - -div.recurrence-widget .form { - padding: .5em 0; -} - -div.recurrence-widget .radio { - margin-left: 0; -} - -div.recurrence-widget .form ul { - margin: 0; - padding: 0; -} - -div.recurrence-widget .form ul li { - list-style-type: none; -} - -div.recurrence-widget .section { - margin: .5em 1em; -} - -div.recurrence-widget .until-count { - margin: 0; - padding: 0; -} - -div.recurrence-widget .until-count li { - margin: 0; - padding: 0; - display: inline; - list-style-type: none; -} - -div.recurrence-widget .until-count .count { - padding-left: 1em; -} - -div.recurrence-widget .monthday .grid { - margin-left: .5em; -} - -div.recurrence-widget .grid { - border: 0; - border-top: 1px solid #ccc; - border-left: 1px solid #ccc; -} - -div.recurrence-widget .grid td { - text-align: center; - border-bottom: 1px solid #ccc; - border-right: 1px solid #ccc; - padding: .8em; - cursor: pointer; -} - -div.recurrence-widget .grid td.active { - background-color: #ddd; -} - -div.recurrence-widget .grid td.empty { - border: 0; -} - -div.recurrence-widget .grid-disabled td.active { - background-color: #ddd; -} - -div.recurrence-widget .disabled { - opacity: .75; - filter: alpha(opacity=75); -} - -div.recurrence-widget .limit ul { - margin-top: .5em; -} - -div.recurrence-widget .weekly .section { - margin: 1em 0; -} - -div.recurrence-widget .weekly td { - width: 2.5em; -} - -div.recurrence-widget .yearly table { - margin: .5em 0 1em 0; -} - -div.recurrence-widget .yearly td { - padding: 1em 1.5em; -} - -div.recurrence-widget .checkbox { - margin-left: 0; -} - -div.recurrence-widget .until-count { - margin-left: 1.5em; -} - -div.recurrence-widget .mode { - padding: .25em 0 1em 0; -} - -div.recurrence-widget .date-selector .calendar-button { - background: url('../img/recurrence-calendar-icon.png') no-repeat center; - padding: .25em; -} - -table.recurrence-calendar { - position: absolute; - background-color: white; - border-top: 1px solid #ccc; - border-left: 1px solid #ccc; - /*outline: 3px solid white;*/ - margin: 0; -} - -table.recurrence-calendar td { - padding: 0; -} - -table.recurrence-calendar a, -table.recurrence-calendar a:link, -table.recurrence-calendar a:visited { - color: #555; - font-weight: bold; -} - -table.recurrence-calendar .year, -table.recurrence-calendar .navigation { - border-right: 1px solid #ccc; -} - -table.recurrence-calendar .body td { - border: 0; - border-bottom: 1px solid #ccc; - border-right: 1px solid #ccc; -} - -table.recurrence-calendar .body td.header { - border-top: 1px solid #ccc; - font-weight: bold; - color: #555; -} - -table.recurrence-calendar .body td.header, -table.recurrence-calendar .body td.day { - padding: .25em; - text-align: center; - vertical-align: center; -} - -table.recurrence-calendar .body td.day { - cursor: pointer; -} - -table.recurrence-calendar .body td.active { - background-color: #ddd; -} - -table.recurrence-calendar .body td.empty { - background-color: #eee; -} - -table.recurrence-calendar .year { - padding-top: .25em; - padding-right: 2em; - text-align: center; -} - -table.recurrence-calendar .navigation { - width: 100%; -} - -table.recurrence-calendar .navigation { - text-align: center; -} - -table.recurrence-calendar .navigation td.prev-year, -table.recurrence-calendar .navigation td.next-year, -table.recurrence-calendar .navigation td.prev-month, -table.recurrence-calendar .navigation td.next-month { - /*width: 1%;*/ - font-size: .8em; -} - -table.recurrence-calendar .remove, -table.recurrence-calendar .remove:link, -table.recurrence-calendar .remove:visited { - float: left; - padding: .1em .25em; - padding-bottom: 0; - font-size: 1.1em; - font-weight: bold; - cursor: pointer; - text-decoration: none; - color: #555; - line-height: 1.2em; -} - -table.recurrence-calendar .remove:hover { - color: #a00; -} - -table.recurrence-calendar .footer { - height: .5em; - overflow: hidden; - border-bottom: 1px solid #ccc; - border-right: 1px solid #ccc; -} - diff --git a/static/recurrence/img/recurrence-calendar-icon.png b/static/recurrence/img/recurrence-calendar-icon.png Binary files differdeleted file mode 100644 index e0d9d86..0000000 --- a/static/recurrence/img/recurrence-calendar-icon.png +++ /dev/null diff --git a/static/recurrence/js/recurrence-widget.js b/static/recurrence/js/recurrence-widget.js deleted file mode 100644 index f63e3b7..0000000 --- a/static/recurrence/js/recurrence-widget.js +++ /dev/null @@ -1,1795 +0,0 @@ -if (!recurrence) - var recurrence = {}; - -recurrence.widget = {}; - - -recurrence.widget.Grid = function(cols, rows) { - this.init(cols, rows); -}; -recurrence.widget.Grid.prototype = { - init: function(cols, rows) { - this.disabled = false; - this.cells = []; - this.cols = cols; - this.rows = rows; - - this.init_dom(); - }, - - init_dom: function() { - var tbody = recurrence.widget.e('tbody'); - for (var y=0; y < this.rows; y++) { - var tr = recurrence.widget.e('tr'); - tbody.appendChild(tr); - for (var x=0; x < this.cols; x++) { - var td = recurrence.widget.e('td'); - tr.appendChild(td); - this.cells.push(td); - } - } - var table = recurrence.widget.e( - 'table', { - 'class': 'grid', 'cellpadding': 0, - 'cellspacing': 0, 'border': 0}, - [tbody]); - - this.elements = {'root': table, 'table': table, 'tbody': tbody}; - }, - - cell: function(col, row) { - return this.elements.tbody.childNodes[row].childNodes[col]; - }, - - enable: function () { - recurrence.widget.remove_class('disabled'); - this.disabled = false; - }, - - disable: function () { - recurrence.widget.add_class('disabled'); - this.disabled = true; - } -}; - - -recurrence.widget.Calendar = function(date, options) { - this.init(date, options); -}; -recurrence.widget.Calendar.prototype = { - init: function(date, options) { - this.date = date || recurrence.widget.date_today(); - this.month = this.date.getMonth(); - this.year = this.date.getFullYear(); - this.options = options || {}; - - if (this.options.onchange) - this.onchange = this.options.onchange; - if (this.options.onclose) - this.onclose = this.options.onclose; - - this.init_dom(); - this.show_month(this.year, this.month); - }, - - init_dom: function() { - var calendar = this; - - // navigation - - var remove = recurrence.widget.e('a', { - 'class': 'remove', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.remove, - 'onclick': function() { - calendar.close(); - } - }, '×'); - var year_prev = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'prev-year', - 'onclick': function() {calendar.show_prev_year();}}, - '<<'); - var year_next = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'next-year', - 'onclick': function() {calendar.show_next_year();}}, - '>>'); - var month_prev = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'prev-month', - 'onclick': function() {calendar.show_prev_month();}}, - '<'); - var month_next = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'next-month', - 'onclick': function() {calendar.show_next_month();}}, - '>'); - var month_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.months[this.month]); - - var header_elements = [ - year_prev, month_prev, month_label, month_next, year_next]; - var header_grid = new recurrence.widget.Grid(header_elements.length, 1); - recurrence.array.foreach(header_elements, function(item, i) { - header_grid.cells[i].appendChild(item); - recurrence.widget.add_class( - header_grid.cells[i], item.className); - }); - recurrence.widget.add_class(header_grid.elements.root, 'navigation'); - - // core - - var calendar_year = recurrence.widget.e( - 'div', {'class': 'year'}, this.year); - var calendar_navigation = header_grid.elements.root; - // var calendar_week = week_grid.elements.root; - var calendar_body = recurrence.widget.e('div', {'class': 'body'}); - var calendar_footer = recurrence.widget.e('div', {'class': 'footer'}); - - var td = recurrence.widget.e( - 'td', {}, - [remove, calendar_year, calendar_navigation, - calendar_body, calendar_footer]); - var tr = recurrence.widget.e('tr', {}, [td]); - var tbody = recurrence.widget.e('tbody', {}, [tr]); - var root = recurrence.widget.e( - 'table', {'class': 'recurrence-calendar'}, [tbody]); - root.style.display = 'none'; - - this.elements = { - 'root': root, - 'year': calendar_year, - 'year_prev': year_prev, - 'year_next': year_next, - 'month_prev': month_prev, - 'month_next': month_next, - 'month_label': month_label, - 'calendar_body': calendar_body - }; - }, - - get_month_grid: function(year, month) { - var calendar = this; - - var dt = new Date(year, month, 1); - var start = dt.getDay(); - var days = recurrence.date.days_in_month(dt); - var rows = Math.ceil((days + start) / 7) + 1; - var grid = new recurrence.widget.Grid(7, rows); - - var number = 1; - recurrence.array.foreach( - grid.cells, function(cell, i) { - var cell = grid.cells[i]; - if (i < 7) { - var weekday_number = i - 1; - if (weekday_number < 0) - weekday_number = 6; - else if (weekday_number > 6) - weekday_number = 0; - cell.innerHTML = recurrence.display.weekdays_oneletter[ - weekday_number]; - recurrence.widget.add_class(cell, 'header'); - } else if (i - 7 < start || number > days) { - recurrence.widget.add_class(cell, 'empty'); - } else { - recurrence.widget.add_class(cell, 'day'); - if (this.date.getDate() == number && - this.date.getFullYear() == dt.getFullYear() && - this.date.getMonth() == dt.getMonth()) - recurrence.widget.add_class(cell, 'active'); - cell.innerHTML = number; - number = number + 1; - cell.onclick = function () { - calendar.set_date( - calendar.year, calendar.month, - parseInt(this.innerHTML, 10)); - }; - } - }, this); - - return grid; - }, - - show_month: function(year, month) { - if (this.elements.calendar_body.childNodes.length) - this.elements.calendar_body.removeChild( - this.elements.calendar_body.childNodes[0]); - this.elements.month_grid = this.get_month_grid(year, month); - this.elements.calendar_body.appendChild( - this.elements.month_grid.elements.root); - this.elements.month_label.firstChild.nodeValue = ( - recurrence.display.months[this.month]); - this.elements.year.firstChild.nodeValue = this.year; - }, - - show_prev_year: function() { - this.year = this.year - 1; - this.show_month(this.year, this.month); - }, - - show_next_year: function() { - this.year = this.year + 1; - this.show_month(this.year, this.month); - }, - - show_prev_month: function() { - this.month = this.month - 1; - if (this.month < 0) { - this.month = 11; - this.year = this.year - 1; - } - this.show_month(this.year, this.month); - }, - - show_next_month: function() { - this.month = this.month + 1; - if (this.month > 11) { - this.month = 0; - this.year = this.year + 1; - } - this.show_month(this.year, this.month); - }, - - set_date: function(year, month, day) { - if (year != this.date.getFullYear() || - month != this.date.getMonth() || - day != this.date.getDate()) { - - this.date.setFullYear(year); - this.date.setMonth(month); - this.date.setDate(day); - - recurrence.array.foreach( - this.elements.month_grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'day')) { - var number = parseInt(cell.innerHTML, 10); - if (number == day) { - recurrence.widget.add_class(cell, 'active'); - } else { - recurrence.widget.remove_class(cell, 'active'); - } - } - }); - - if (this.onchange) - this.onchange(this.date); - } - }, - - set_position: function(x, y) { - this.elements.root.style.left = x + 'px'; - this.elements.root.style.top = y + 'px'; - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - }, - - close: function() { - if (this.elements.root.parentNode) { - this.elements.root.parentNode.removeChild(this.elements.root); - if (this.onclose) - this.onclose(); - } - } -}; - - -recurrence.widget.DateSelector = function(date, options) { - this.init(date, options); -}; -recurrence.widget.DateSelector.prototype = { - init: function(date, options) { - this.disabled = false; - this.date = date; - this.calendar = null; - this.options = options || {}; - - if (this.options.onchange) - this.onchange = this.options.onchange; - - this.init_dom(); - }, - - init_dom: function() { - var dateselector = this; - - if (this.date) - var date_value = recurrence.date.format(this.date, '%Y-%m-%d'); - else - var date_value = ''; - var date_field = recurrence.widget.e( - 'input', { - 'class': 'date-field', 'size': 10, - 'value': date_value, - 'onchange': function() {dateselector.set_date(this.value);}}); - var calendar_button = recurrence.widget.e( - 'a', { - 'class': 'calendar-button', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.calendar, - 'onclick': function() { - if (!dateselector.disabled) - dateselector.show_calendar(); - } - }, - ' '); - var root = recurrence.widget.e( - 'span', {'class': 'date-selector'}, - [date_field, calendar_button]); - - this.elements = { - 'root': root, - 'date_field': date_field, - 'calendar_button': calendar_button - }; - }, - - show_calendar: function() { - var dateselector = this; - - var calendar_blur = function(event) { - var element = event.target; - var is_in_dom = recurrence.widget.element_in_dom( - element, dateselector.calendar.elements.root); - if (!is_in_dom && - element != dateselector.elements.calendar_button) { - // clicked outside of calendar - dateselector.calendar.close(); - if (window.detachEvent) - window.detachEvent('onclick', calendar_blur); - else - window.removeEventListener('click', calendar_blur, false); - } - }; - - if (!this.calendar) { - this.calendar = new recurrence.widget.Calendar( - new Date((this.date || recurrence.widget.date_today()).valueOf()), { - 'onchange': function() { - dateselector.set_date( - recurrence.date.format(this.date, '%Y-%m-%d')); - dateselector.calendar.close(); - }, - 'onclose': function() { - if (window.detachEvent) - window.detachEvent('onclick', calendar_blur); - else - window.removeEventListener( - 'click', calendar_blur, false); - dateselector.hide_calendar(); - } - }); - document.body.appendChild(this.calendar.elements.root); - - this.calendar.show(); - this.set_calendar_position(); - - if (window.attachEvent) - window.attachEvent('onclick', calendar_blur); - else - window.addEventListener('click', calendar_blur, false); - } - }, - - set_date: function(datestring) { - var tokens = datestring.split('-'); - var year = parseInt(tokens[0], 10); - var month = parseInt(tokens[1], 10) - 1; - var day = parseInt(tokens[2], 10); - var dt = new Date(year, month, day); - - if (String(dt) == 'Invalid Date' || String(dt) == 'NaN') { - if (this.date && !this.options.allow_null) { - this.elements.date_field.value = recurrence.date.format( - this.date, '%Y-%m-%d'); - } else { - if (this.elements.date_field.value != '') { - if (this.onchange) - this.onchange(null); - } - this.elements.date_field.value = ''; - } - } else { - if (!this.date || - (year != this.date.getFullYear() || - month != this.date.getMonth() || - day != this.date.getDate())) { - - if (!this.date) - this.date = recurrence.widget.date_today(); - this.date.setFullYear(year); - this.date.setMonth(month); - this.date.setDate(day); - - this.elements.date_field.value = datestring; - - if (this.onchange) - this.onchange(this.date); - } - } - }, - - set_calendar_position: function() { - var loc = recurrence.widget.cumulative_offset( - this.elements.calendar_button); - - var calendar_x = loc[0]; - var calendar_y = loc[1]; - var calendar_right = ( - loc[0] + this.calendar.elements.root.clientWidth); - var calendar_bottom = ( - loc[1] + this.calendar.elements.root.clientHeight); - - if (calendar_right > document.scrollWidth) - calendar_x = calendar_x - ( - calendar_right - document.scrollWidth); - if (calendar_bottom > document.scrollHeight) - calendar_y = calendar_y - ( - calendar_bottom - document.scrollHeight); - - this.calendar.set_position(calendar_x, calendar_y); - }, - - hide_calendar: function() { - this.calendar = null; - }, - - enable: function () { - this.disabled = false; - this.elements.date_field.disabled = false; - }, - - disable: function () { - this.disabled = true; - this.elements.date_field.disabled = true; - if (this.calendar) - this.calendar.close(); - } -}; - - -recurrence.widget.Widget = function(textarea, options) { - this.init(textarea, options); -}; -recurrence.widget.Widget.prototype = { - init: function(textarea, options) { - if (textarea.toLowerCase) - textarea = document.getElementById(textarea); - this.selected_panel = null; - this.panels = []; - this.data = recurrence.deserialize(textarea.value); - this.textarea = textarea; - this.options = options; - - this.default_freq = options.default_freq || recurrence.WEEKLY; - - this.init_dom(); - this.init_panels(); - }, - - init_dom: function() { - var widget = this; - - var panels = recurrence.widget.e('div', {'class': 'panels'}); - var control = recurrence.widget.e('div', {'class': 'control'}); - var root = recurrence.widget.e( - 'div', {'class': this.textarea.className}, [panels, control]); - - var add_rule = new recurrence.widget.AddButton( - recurrence.display.labels.add_rule, { - 'onclick': function () {widget.add_rule();} - }); - recurrence.widget.add_class(add_rule.elements.root, 'add-rule'); - control.appendChild(add_rule.elements.root); - - var add_date = new recurrence.widget.AddButton( - recurrence.display.labels.add_date, { - 'onclick': function () {widget.add_date();} - }); - recurrence.widget.add_class(add_date.elements.root, 'add-date'); - control.appendChild(add_date.elements.root); - - this.elements = { - 'root': root, - 'panels': panels, - 'control': control - }; - - // attach immediately - this.textarea.style.display = 'none'; - this.textarea.parentNode.insertBefore( - this.elements.root, this.textarea); - }, - - init_panels: function() { - recurrence.array.foreach( - this.data.rrules, function(item) { - this.add_rule_panel(recurrence.widget.INCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.exrules, function(item) { - this.add_rule_panel(recurrence.widget.EXCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.rdates, function(item) { - this.add_date_panel(recurrence.widget.INCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.exdates, function(item) { - this.add_date_panel(recurrence.widget.EXCLUSION, item); - }, this); - }, - - add_rule_panel: function(mode, rule) { - var panel = new recurrence.widget.Panel(this); - var form = new recurrence.widget.RuleForm(panel, mode, rule); - - panel.onexpand = function() { - if (panel.widget.selected_panel) - if (panel.widget.selected_panel != this) - panel.widget.selected_panel.collapse(); - panel.widget.selected_panel = this; - }; - panel.onremove = function() { - form.remove(); - }; - - this.elements.panels.appendChild(panel.elements.root); - this.panels.push(panel); - this.update(); - return panel; - }, - - add_date_panel: function(mode, date) { - var panel = new recurrence.widget.Panel(this); - var form = new recurrence.widget.DateForm(panel, mode, date); - - panel.onexpand = function() { - if (panel.widget.selected_panel) - if (panel.widget.selected_panel != this) - panel.widget.selected_panel.collapse(); - panel.widget.selected_panel = this; - }; - panel.onremove = function() { - form.remove(); - }; - - this.elements.panels.appendChild(panel.elements.root); - this.panels.push(panel); - this.update(); - return panel; - }, - - add_rule: function(rule) { - var rule = rule || new recurrence.Rule(this.default_freq); - this.data.rrules.push(rule); - this.add_rule_panel(recurrence.widget.INCLUSION, rule).expand(); - }, - - add_date: function(date) { - var date = date || recurrence.widget.date_today(); - this.data.rdates.push(date); - this.add_date_panel(recurrence.widget.INCLUSION, date).expand(); - }, - - update: function() { - this.textarea.value = this.data.serialize(); - } -}; - - -recurrence.widget.AddButton = function(label, options) { - this.init(label, options); -}; -recurrence.widget.AddButton.prototype = { - init: function(label, options) { - this.label = label; - this.options = options || {}; - - this.init_dom(); - }, - - init_dom: function() { - var addbutton = this; - - var plus = recurrence.widget.e( - 'span', {'class': 'plus'}, '+'); - var label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, this.label); - var root = recurrence.widget.e( - 'a', {'class': 'add-button', 'href': 'javascript:void(0)'}, - [plus, label]); - - root.onclick = function() { - addbutton.options.onclick(); - }; - - this.elements = {'root': root, 'plus': plus, 'label': label}; - } -}; - - -recurrence.widget.Panel = function(widget, options) { - this.init(widget, options); -}; -recurrence.widget.Panel.prototype = { - init: function(widget, options) { - this.collapsed = false; - this.widget = widget; - this.options = options || {}; - - if (this.options.onremove) - this.onremove = this.options.onremove; - if (this.options.onexpand) - this.onexpand = this.options.onexpand; - if (this.options.oncollapse) - this.oncollapse = this.options.oncollapse; - - this.init_dom(); - }, - - init_dom: function() { - var panel = this; - - var remove = recurrence.widget.e('a', { - 'class': 'remove', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.remove, - 'onclick': function() { - panel.remove(); - } - }, '×'); - var label = recurrence.widget.e('a', { - 'class': 'recurrence-label', - 'href': 'javascript:void(0)', - 'onclick': function() { - if (panel.collapsed) - panel.expand(); - else - panel.collapse(); - } - }, ' '); - var header = recurrence.widget.e( - 'div', {'class': 'header'}, [remove, label]); - var body = recurrence.widget.e( - 'div', {'class': 'body'}); - var root = recurrence.widget.e( - 'div', {'class': 'panel'}, [header, body]); - - this.elements = { - 'root': root, 'remove': remove, 'label': label, - 'header': header, 'body': body - }; - - this.collapse(); - }, - - set_label: function(label) { - this.elements.label.innerHTML = label; - }, - - set_body: function(element) { - if (this.elements.body.childNodes.length) - this.elements.body.removeChild(this.elements.body.childNodes[0]); - this.elements.body.appendChild(element); - }, - - expand: function() { - this.collapsed = false; - this.elements.body.style.display = ''; - if (this.onexpand) - this.onexpand(this); - }, - - collapse: function() { - this.collapsed = true; - this.elements.body.style.display = 'none'; - if (this.oncollapse) - this.oncollapse(this); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.onremove) - this.onremove(parent); - } -}; - - -recurrence.widget.RuleForm = function(panel, mode, rule, options) { - this.init(panel, mode, rule, options); -}; -recurrence.widget.RuleForm.prototype = { - init: function(panel, mode, rule, options) { - this.selected_freq = rule.freq; - this.panel = panel; - this.mode = mode; - this.rule = rule; - this.options = options || {}; - - var rule_options = { - interval: rule.interval, until: rule.until, count: rule.count - }; - - this.freq_rules = [ - new recurrence.Rule(recurrence.YEARLY, rule_options), - new recurrence.Rule(recurrence.MONTHLY, rule_options), - new recurrence.Rule(recurrence.WEEKLY, rule_options), - new recurrence.Rule(recurrence.DAILY, rule_options) - ]; - this.freq_rules[this.rule.freq].update(this.rule); - - this.init_dom(); - - this.set_freq(this.selected_freq); - }, - - init_dom: function() { - var form = this; - - // mode - - var mode_checkbox = recurrence.widget.e( - 'input', {'class': 'checkbox', 'type': 'checkbox', 'name': 'mode'}); - var mode_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.exclude_occurrences); - var mode_container = recurrence.widget.e( - 'div', {'class': 'mode'}, - [mode_checkbox, mode_label]); - if (this.mode == recurrence.widget.EXCLUSION) - // delay for ie6 compatibility - setTimeout(function() { - mode_checkbox.checked = true; - recurrence.widget.add_class(form.panel, 'exclusion'); - }, 10); - - // freq - - var freq_choices = recurrence.display.frequencies.slice(0, 4); - var freq_options = recurrence.array.foreach( - freq_choices, function(item, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, - recurrence.string.capitalize(item)); - return option; - }); - var freq_select = recurrence.widget.e( - 'select', {'name': 'freq'}, freq_options); - var freq_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.frequency + ':'); - var freq_container = recurrence.widget.e( - 'div', {'class': 'freq'}, - [freq_label, freq_select]); - - // interval - - var interval_field = recurrence.widget.e( - 'input', { - 'name': 'interval', 'size': 1, 'value': this.rule.interval}); - var interval_label1 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.every); - var interval_label2 = recurrence.widget.e( - 'span', {'class': 'laebl'}, - recurrence.display.timeintervals_plural[this.rule.freq]); - var interval_container = recurrence.widget.e( - 'div', {'class': 'interval'}, - [interval_label1, interval_field, interval_label2]); - - // until - - if (this.rule.until) - until_value = recurrence.date.format(this.rule.until, '%Y-%m-%d'); - else - until_value = ''; - var until_radio = recurrence.widget.e( - 'input', {'class': 'radio', 'type': 'radio', - 'name': 'until_count', 'value': 'until'}); - var until_date_selector = new recurrence.widget.DateSelector( - this.rule.until, { - 'onchange': function(date) {form.set_until(date);}, - 'allow_null': true - }); - var until_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.date + ':'); - var until_container = recurrence.widget.e( - 'li', {'class': 'until'}, - [until_radio, until_label, until_date_selector.elements.root]); - - // count - - if (this.rule.count) - count_value = this.rule.count; - else - count_value = 1; - var count_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'until_count', 'value': 'count'}); - var count_field = recurrence.widget.e( - 'input', {'name': 'count', 'size': 1, 'value': count_value}); - if (this.rule.count && this.rule.count < 2) - var token = recurrence.string.capitalize( - recurrence.display.labels.count); - else - var token = recurrence.string.capitalize( - recurrence.display.labels.count_plural); - var count_label1 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, token.split('%(number)s')[0]); - var count_label2 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, token.split('%(number)s')[1]); - var count_container = recurrence.widget.e( - 'li', {'class': 'count'}, - [count_radio, count_label1, count_field, count_label2]); - - // limit container - - var until_count_container = recurrence.widget.e( - 'ul', {'class': 'until-count'}, - [until_container, count_container]); - var limit_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', - 'name': 'limit'}); - var limit_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.repeat_until + ':'); - var limit_container = recurrence.widget.e( - 'div', {'class': 'limit'}, - [limit_checkbox, limit_label, until_count_container]); - if (this.rule.until || this.rule.count) { - // compatibility with ie, we delay - setTimeout(function() {limit_checkbox.checked = true;}, 10); - } else { - until_radio.disabled = true; - count_radio.disabled = true; - until_date_selector.disable(); - recurrence.widget.add_class(until_count_container, 'disabled'); - } - - // core - - var freq_form_container = recurrence.widget.e( - 'div', {'class': 'form'}); - var root = recurrence.widget.e( - 'form', {}, [ - mode_container, freq_container, interval_container, - freq_form_container, limit_container]); - - // events - - mode_checkbox.onclick = function() { - if (this.checked) - form.set_mode(recurrence.widget.EXCLUSION); - else - form.set_mode(recurrence.widget.INCLUSION); - }; - - freq_select.onchange = function() { - form.set_freq(parseInt(this.value), 10); - }; - - interval_field.onchange = function() { - form.set_interval(parseInt(this.value), 10); - }; - - limit_checkbox.onclick = function () { - if (this.checked) { - recurrence.widget.remove_class( - until_count_container, 'disabled'); - until_radio.disabled = false; - count_radio.disabled = false; - if (until_radio.checked) { - until_date_selector.enable(); - form.set_until(until_date_selector.date); - } - if (count_radio.checked) { - count_field.disabled = false; - form.set_count(parseInt(count_field.value)); - } - } else { - recurrence.widget.add_class( - until_count_container, 'disabled'); - until_radio.disabled = true; - count_radio.disabled = true; - until_date_selector.disable(); - count_field.disabled = true; - recurrence.array.foreach( - form.freq_rules, function(rule) { - rule.until = null; - rule.count = null; - }); - form.update(); - } - } - - // for compatibility with ie, use timeout - setTimeout(function () { - if (form.rule.count) { - count_radio.checked = true; - until_date_selector.disable(); - } else { - until_radio.checked = true; - count_field.disabled = true; - } - }, 1); - - until_radio.onclick = function () { - this.checked = true; - until_date_selector.enable(); - count_radio.checked = false; - count_field.disabled = true; - form.set_until(until_date_selector.date); - }; - - count_radio.onclick = function () { - this.checked = true; - count_field.disabled = false; - until_radio.checked = false; - until_date_selector.disable(); - form.set_count(parseInt(count_field.value), 10); - }; - - count_field.onchange = function () { - form.set_count(parseInt(this.value), 10); - }; - - // freq forms - - var forms = [ - recurrence.widget.RuleYearlyForm, - recurrence.widget.RuleMonthlyForm, - recurrence.widget.RuleWeeklyForm, - recurrence.widget.RuleDailyForm - ]; - var freq_forms = recurrence.array.foreach( - forms, function(form, i) { - var rule = this.freq_rules[i]; - var f = new form(this, rule); - freq_form_container.appendChild(f.elements.root); - return f; - }, this); - - this.freq_forms = freq_forms; - - // install dom - - this.panel.set_label(this.get_display_text()); - this.panel.set_body(root); - - this.elements = { - 'root': root, - 'mode_checkbox': mode_checkbox, - 'freq_select': freq_select, - 'interval_field': interval_field, - 'freq_form_container': freq_form_container, - 'until_radio': until_radio, - 'count_field': count_field, - 'count_radio': count_radio, - 'limit_checkbox': limit_checkbox - }; - }, - - get_display_text: function() { - var text = this.freq_rules[this.selected_freq].get_display_text(); - if (this.mode == recurrence.widget.EXCLUSION) - text = recurrence.display.mode.exclusion + ' ' + text; - return recurrence.string.capitalize(text); - }, - - set_until: function(until) { - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.count = null; - rule.until = until; - }); - this.update(); - }, - - set_count: function(count) { - if (count < 2) - var token = recurrence.string.capitalize( - recurrence.display.labels.count); - else - var token = recurrence.string.capitalize( - recurrence.display.labels.count_plural); - var label1 = this.elements.count_field.previousSibling; - var label2 = this.elements.count_field.nextSibling; - label1.firstChild.nodeValue = token.split('%(number)s')[0]; - label2.firstChild.nodeValue = token.split('%(number)s')[1]; - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.until = null; - rule.count = count; - }); - this.update(); - }, - - set_interval: function(interval) { - interval = parseInt(interval, 10); - if (String(interval) == 'NaN') { - // invalid value, reset to previous value - this.elements.interval_field.value = ( - this.freq_rules[this.selected_freq].interval); - return; - } - - var label = this.elements.interval_field.nextSibling; - - if (interval < 2) - label.firstChild.nodeValue = ( - recurrence.display.timeintervals[this.selected_freq]); - else - label.firstChild.nodeValue = ( - recurrence.display.timeintervals_plural[this.selected_freq]); - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.interval = interval; - }); - - this.elements.interval_field.value = interval; - this.update(); - }, - - set_freq: function(freq) { - this.freq_forms[this.selected_freq].hide(); - this.freq_forms[freq].show(); - this.elements.freq_select.value = freq; - this.selected_freq = freq; - // need to update interval to display different label - this.set_interval(parseInt(this.elements.interval_field.value), 10); - this.update(); - }, - - set_mode: function(mode) { - if (this.mode != mode) { - if (this.mode == recurrence.widget.INCLUSION) { - recurrence.array.remove( - this.panel.widget.data.rrules, this.rule); - this.panel.widget.data.exrules.push(this.rule); - recurrence.widget.remove_class( - this.panel.elements.root, 'inclusion'); - recurrence.widget.add_class( - this.panel.elements.root, 'exclusion'); - } else { - recurrence.array.remove( - this.panel.widget.data.exrules, this.rule); - this.panel.widget.data.rrules.push(this.rule); - recurrence.widget.remove_class( - this.panel.elements.root, 'exclusion'); - recurrence.widget.add_class( - this.panel.elements.root, 'inclusion'); - } - this.mode = mode; - } - this.update(); - }, - - update: function() { - this.panel.set_label(this.get_display_text()); - this.rule.update(this.freq_rules[this.selected_freq]); - this.panel.widget.update(); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.mode == recurrence.widget.INCLUSION) - recurrence.array.remove(this.panel.widget.data.rrules, this.rule); - else - recurrence.array.remove(this.panel.widget.data.exrules, this.rule); - this.panel.widget.update(); - } -}; - - -recurrence.widget.RuleYearlyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleYearlyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - var grid = new recurrence.widget.Grid(4, 3); - var number = 0; - for (var y=0; y < 3; y++) { - for (var x=0; x < 4; x++) { - var cell = grid.cell(x, y); - if (this.rule.bymonth.indexOf(number + 1) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.value = number + 1; - cell.innerHTML = recurrence.display.months_short[number]; - cell.onclick = function () { - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_bymonth(); - }; - number += 1; - } - } - - // by weekday checkbox - - var byday_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', - 'name': 'byday'}); - var byday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.string.capitalize( - recurrence.display.labels.on_the) + ':'); - var byday_container = recurrence.widget.e( - 'div', {'class': 'byday'}, - [byday_checkbox, byday_label]); - - // weekday-position - - var position_options = recurrence.array.foreach( - [1, 2, 3, 4, -1, -2, -3], function(value) { - var option = recurrence.widget.e( - 'option', {'value': value}, - recurrence.string.strip(recurrence.display.weekdays_position[ - String(value)].split('%(weekday)s')[0])); - return option; - }); - var position_select = recurrence.widget.e( - 'select', {'name': 'position'}, position_options); - var weekday_options = recurrence.array.foreach( - recurrence.display.weekdays, function(weekday, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, weekday); - return option; - }); - var weekday_select = recurrence.widget.e( - 'select', {'name': 'weekday'}, weekday_options); - var weekday_position_container = recurrence.widget.e( - 'div', {'class': 'section'}, [position_select, weekday_select]); - - // core - - var year = recurrence.widget.e('div'); - year.appendChild(grid.elements.root); - - var root = recurrence.widget.e( - 'div', {'class': 'yearly'}, - [year, byday_container, weekday_position_container]); - root.style.display = 'none'; - - if (this.rule.byday.length) { - if (form.rule.bysetpos.length) { - position_select.value = String(form.rule.bysetpos[0]); - } else { - position_select.value = String(form.rule.byday[0].index); - } - weekday_select.value = String(form.rule.byday[0].number); - byday_checkbox.checked = true; - } else { - position_select.disabled = true; - weekday_select.disabled = true; - } - - // events - - byday_checkbox.onclick = function () { - if (this.checked) { - position_select.disabled = false; - weekday_select.disabled = false; - form.set_byday(); - } else { - position_select.disabled = true; - weekday_select.disabled = true; - form.rule.byday = []; - form.panel.update(); - } - }; - - position_select.onchange = function () { - form.set_byday(); - }; - - weekday_select.onchange = function () { - form.set_byday(); - }; - - this.elements = { - 'root': root, - 'grid': grid, - 'byday_checkbox': byday_checkbox, - 'position_select': position_select, - 'weekday_select': weekday_select - }; - }, - - get_weekday: function() { - var number = parseInt(this.elements.weekday_select.value, 10); - var index = parseInt(this.elements.position_select.value, 10); - return new recurrence.Weekday(number, index); - }, - - set_bymonth: function() { - var bymonth = []; - recurrence.array.foreach( - this.elements.grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'active')) - bymonth.push(cell.value); - }) - this.rule.bymonth = bymonth; - this.panel.update(); - }, - - set_byday: function() { - this.rule.byday = [this.get_weekday()]; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleMonthlyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleMonthlyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - // monthday - - var monthday_grid = new recurrence.widget.Grid(7, Math.ceil(31 / 7)); - var number = 0; - for (var y=0; y < Math.ceil(31 / 7); y++) { - for (var x=0; x < 7; x++) { - number += 1; - var cell = monthday_grid.cell(x, y); - if (number > 31) { - recurrence.widget.add_class(cell, 'empty'); - continue; - } else { - cell.innerHTML = number; - if (this.rule.bymonthday.indexOf(number) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.onclick = function () { - if (monthday_grid.disabled) - return; - var day = parseInt(this.innerHTML, 10) || null; - if (day) { - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_bymonthday(); - } - } - } - } - } - var monthday_grid_container = recurrence.widget.e( - 'div', {'class': 'section'}); - monthday_grid_container.appendChild(monthday_grid.elements.root); - var monthday_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'monthly', 'value': 'monthday'}); - var monthday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.each + ':'); - var monthday_container = recurrence.widget.e( - 'li', {'class': 'monthday'}, - [monthday_radio, monthday_label, monthday_grid_container]); - - // weekday-position - - var position_options = recurrence.array.foreach( - [1, 2, 3, 4, -1, -2, -3], function(value) { - var option = recurrence.widget.e( - 'option', {'value': value}, - recurrence.string.strip( - recurrence.display.weekdays_position[ - String(value)].split('%(weekday)s')[0])); - return option; - }); - var position_select = recurrence.widget.e( - 'select', {'name': 'position'}, position_options); - - var weekday_options = recurrence.array.foreach( - recurrence.display.weekdays, function(weekday, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, weekday); - return option; - }); - var weekday_select = recurrence.widget.e( - 'select', {'name': 'weekday'}, weekday_options); - var weekday_position_container = recurrence.widget.e( - 'div', {'class': 'section'}, [position_select, weekday_select]); - var weekday_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'monthly', 'value': 'weekday'}); - var weekday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.on_the + ':'); - var weekday_container = recurrence.widget.e( - 'li', {'class': 'weekday'}, - [weekday_radio, weekday_label, weekday_position_container]); - - // core - - var monthday_weekday_container = recurrence.widget.e( - 'ul', {'class': 'monthly'}, - [monthday_container, weekday_container]); - - var root = recurrence.widget.e( - 'div', {'class': 'monthly'}, [monthday_weekday_container]); - root.style.display = 'none'; - - // events - - // for compatibility with ie, use timeout - setTimeout(function () { - if (form.rule.byday.length) { - weekday_radio.checked = true; - if (form.rule.bysetpos.length) { - position_select.value = String(form.rule.bysetpos[0]); - } else { - position_select.value = String(form.rule.byday[0].index); - } - weekday_select.value = String(form.rule.byday[0].number); - monthday_grid.disable(); - } else { - monthday_radio.checked = true; - position_select.disabled = true; - weekday_select.disabled = true; - } - }, 1); - - monthday_radio.onclick = function () { - this.checked = true; - weekday_radio.checked = false; - position_select.disabled = true; - weekday_select.disabled = true; - monthday_grid.enable(); - form.set_bymonthday(); - }; - - weekday_radio.onclick = function () { - this.checked = true; - monthday_radio.checked = false; - position_select.disabled = false; - weekday_select.disabled = false; - monthday_grid.disable(); - form.set_byday(); - }; - - position_select.onchange = function () { - form.set_byday(); - }; - - weekday_select.onchange = function () { - form.set_byday(); - }; - - this.elements = { - 'root': root, - 'monthday_grid': monthday_grid, - 'monthday_radio': monthday_radio, - 'weekday_radio': weekday_radio, - 'position_select': position_select, - 'weekday_select': weekday_select - }; - }, - - get_weekday: function() { - var number = parseInt(this.elements.weekday_select.value, 10); - var index = parseInt(this.elements.position_select.value, 10); - return new recurrence.Weekday(number, index); - }, - - set_byday: function() { - this.rule.bymonthday = []; - this.rule.bysetpos = []; - this.rule.byday = [this.get_weekday()]; - this.panel.update(); - }, - - set_bymonthday: function() { - this.rule.bysetpos = []; - this.rule.byday = []; - var monthdays = []; - recurrence.array.foreach( - this.elements.monthday_grid.cells, function(cell) { - var day = parseInt(cell.innerHTML, 10) || null; - if (day && recurrence.widget.has_class(cell, 'active')) - monthdays.push(day); - }); - this.rule.bymonthday = monthdays; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleWeeklyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleWeeklyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - var weekday_grid = new recurrence.widget.Grid(7, 1); - var days = []; - var days = recurrence.array.foreach( - this.rule.byday, function(day) { - return recurrence.to_weekday(day).number; - }); - for (var x=0; x < 7; x++) { - var cell = weekday_grid.cell(x, 0); - if (days.indexOf(x) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.value = x; - cell.innerHTML = recurrence.display.weekdays_short[x]; - cell.onclick = function () { - if (weekday_grid.disabled) - return; - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_byday(); - }; - } - - var weekday_container = recurrence.widget.e( - 'div', {'class': 'section'}); - weekday_container.appendChild(weekday_grid.elements.root); - var root = recurrence.widget.e( - 'div', {'class': 'weekly'}, [weekday_container]); - root.style.display = 'none'; - - this.elements = { - 'root': root, - 'weekday_grid': weekday_grid - }; - }, - - set_byday: function() { - var byday = []; - recurrence.array.foreach( - this.elements.weekday_grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'active')) - byday.push(new recurrence.Weekday(cell.value)); - }); - this.rule.byday = byday; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleDailyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleDailyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var root = recurrence.widget.e('div', {'class': 'daily'}); - root.style.display = 'none'; - this.elements = {'root': root}; - }, - - show: function() { - // this.elements.root.style.display = ''; - }, - - hide: function() { - // this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.DateForm = function(panel, mode, date) { - this.init(panel, mode, date); -}; -recurrence.widget.DateForm.prototype = { - init: function(panel, mode, date) { - this.collapsed = true; - this.panel = panel; - this.mode = mode; - this.date = date; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - // mode - - var mode_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', 'name': 'mode', - 'onclick': function() { - if (this.checked) - form.set_mode(recurrence.widget.EXCLUSION); - else - form.set_mode(recurrence.widget.INCLUSION); - } - }); - if (this.mode == recurrence.widget.EXCLUSION) - mode_checkbox.checked = true; - var mode_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.exclude_date); - var mode_container = recurrence.widget.e( - 'div', {'class': 'mode'}, [mode_checkbox, mode_label]); - - // date - - var date_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, recurrence.display.labels.date + ':'); - var date_selector = new recurrence.widget.DateSelector( - this.date, {'onchange': function() {form.update();}}); - var date_container = recurrence.widget.e( - 'div', {'class': 'date'}, [date_label, date_selector.elements.root]); - - // core - - var root = recurrence.widget.e( - 'form', {'class': 'date'}, [mode_container, date_container]); - - // init dom - - this.panel.set_label(this.get_display_text()); - this.panel.set_body(root); - this.elements = {'root': root}; - }, - - get_display_text: function() { - var text = recurrence.date.format(this.date, pgettext('date', '%l, %F %j, %Y')); - if (this.mode == recurrence.widget.EXCLUSION) - text = recurrence.display.mode.exclusion + ' ' + text; - return recurrence.string.capitalize(text); - }, - - set_mode: function(mode) { - if (this.mode != mode) { - if (this.mode == recurrence.widget.INCLUSION) { - recurrence.array.remove( - this.panel.widget.data.rdates, this.date); - this.panel.widget.data.exdates.push(this.date); - recurrence.widget.remove_class( - this.elements.root, 'inclusion'); - recurrence.widget.add_class( - this.elements.root, 'exclusion'); - this.update(); - } else { - recurrence.array.remove( - this.panel.widget.data.exdates, this.date); - this.panel.widget.data.rdates.push(this.date); - recurrence.widget.remove_class( - this.elements.root, 'exclusion'); - recurrence.widget.add_class( - this.elements.root, 'inclusion'); - this.update(); - } - this.mode = mode; - } - this.update(); - }, - - update: function() { - this.panel.set_label(this.get_display_text()); - this.panel.widget.update(); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.mode == recurrence.widget.INCLUSION) - recurrence.array.remove(this.panel.widget.data.rdates, this.date); - else - recurrence.array.remove(this.panel.widget.data.exdates, this.date); - this.panel.widget.update(); - } -}; - - -recurrence.widget.e = function(tag_name, attrs, inner) { - var element = document.createElement(tag_name); - if (attrs) - recurrence.widget.set_attrs(element, attrs); - if (inner) { - if (!inner.toLowerCase && inner.length) - recurrence.array.foreach( - inner, function(e) {element.appendChild(e);}); - else - element.innerHTML = inner; - } - return element; -}; - - -recurrence.widget.set_attrs = function(element, attrs) { - for (var attname in attrs) - if (attname.match(/^on/g)) - element[attname] = attrs[attname]; - else if (attname == 'class') - element.className = attrs[attname]; - else - element.setAttribute(attname, attrs[attname]); -}; - - -recurrence.widget.add_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) == -1) { - names.push(class_name); - element.className = names.join(' '); - } -}; - - -recurrence.widget.remove_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) > -1) { - recurrence.array.remove(names, class_name); - element.className = names.join(' '); - } -}; - - -recurrence.widget.has_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) > -1) - return true; - else - return false; -}; - - -recurrence.widget.element_in_dom = function(element, dom) { - if (element == dom) { - return true; - } else { - for (var i=0; i < dom.childNodes.length; i++) - if (recurrence.widget.element_in_dom(element, dom.childNodes[i])) - return true; - } - return false; -}; - - -recurrence.widget.cumulative_offset = function(element) { - var y = 0, x = 0; - do { - y += element.offsetTop || 0; - x += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [x, y]; -}; - - -recurrence.widget.textareas_to_widgets = function(token) { - var elements = []; - if (!token) - token = 'recurrence-widget'; - if (token.toLowerCase) { - var textareas = document.getElementsByTagName('textarea'); - recurrence.array.foreach( - textareas, function(textarea) { - if (recurrence.widget.has_class(textarea, token)) - elements.push(textarea); - }); - } - recurrence.array.foreach( - elements, function(e) { - new recurrence.widget.Widget(e, window[e.id] || {}); - }); -}; - - -recurrence.widget.date_today = function() { - var date = new Date(); - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - return date; -}; - - -recurrence.widget.INCLUSION = true; -recurrence.widget.EXCLUSION = false; - - -// display - - -if (!recurrence.display) - recurrence.display = {}; - -recurrence.display.mode = { - 'inclusion': gettext('including'), 'exclusion': gettext('excluding') -}; - -recurrence.display.labels = { - 'frequency': gettext('Frequency'), - 'on_the': gettext('On the'), - 'each': gettext('Each'), - 'every': gettext('Every'), - 'until': gettext('Until'), - 'count': gettext('Occurs %(number)s time'), - 'count_plural': gettext('Occurs %(number)s times'), - 'date': gettext('Date'), - 'time': gettext('Time'), - 'repeat_until': gettext('Repeat until'), - 'exclude_occurrences': gettext('Exclude these occurences'), - 'exclude_date': gettext('Exclude this date'), - 'add_rule': gettext('Add rule'), - 'add_date': gettext('Add date'), - 'remove': gettext('Remove'), - 'calendar': gettext('Calendar') -}; diff --git a/static/recurrence/js/recurrence.js b/static/recurrence/js/recurrence.js deleted file mode 100644 index 8c00fe3..0000000 --- a/static/recurrence/js/recurrence.js +++ /dev/null @@ -1,1105 +0,0 @@ -if (!recurrence) - var recurrence = {}; - - -recurrence.Rule = function(freq, options) { - this.init(freq, options); -}; -recurrence.Rule.prototype = { - init: function(freq, options) { - this.freq = freq; - - options = options || {}; - this.interval = options.interval || 1; - this.wkst = options.wkst || null; - this.count = options.count || null; - this.until = options.until || null; - - recurrence.array.foreach( - recurrence.byparams, function (param) { - if (options[param]) { - var value = options[param]; - if (value == null) - value = []; - this[param] = recurrence.array.from(value); - } else { - this[param] = []; - } - }, this); - }, - - copy: function() { - var until = this.until; - if (until) - until = new Date(until.valueOf()); - var rule = new recurrence.Rule(this.freq, this); - rule.until = until; - return rule; - }, - - update: function(rule) { - rule = rule.copy(); - this.freq = rule.freq; - this.interval = rule.interval; - this.wkst = rule.wkst; - this.until = rule.until; - this.count = rule.count; - - recurrence.array.foreach( - recurrence.byparams, function(param) { - this[param] = rule[param]; - }, this); - }, - - get_display_text: function(short) { - short = short || false; - var parts = []; - - var get_position_display = function(position) { - if (short) - return recurrence.display.weekdays_position_short[ - String(position)]; - else - return recurrence.display.weekdays_position[ - String(position)]; - }; - var get_weekday_display = function(number) { - if (short) - return recurrence.display.weekdays_short[number]; - else - return recurrence.display.weekdays[number]; - }; - var get_position_weekday = function(rule) { - var items = []; - if (rule.bysetpos.length && rule.byday.length) { - recurrence.array.foreach( - rule.bysetpos, function(x) { - var label = get_position_display(x || 1); - recurrence.array.foreach( - rule.byday, function(y) { - var weekday_display = get_weekday_display( - recurrence.to_weekday(y).number); - items.push( - interpolate( - label, {'weekday': weekday_display}, true)); - }); - }); - - } else if (rule.byday.length) { - // TODO byday Weekday objects without index means - // every weekday in the month, and so should appear in - // plural. i.e. 'on sundays' instead of - // 'on the first sunday'. - recurrence.array.foreach( - rule.byday, function(x, i) { - var label = get_position_display(x.index || 1); - var weekday_display = get_weekday_display( - recurrence.to_weekday(x).number); - items.push( - interpolate( - label, {'weekday': weekday_display}, true)); - }); - } - return items.join(', '); - } - - if (this.interval > 1) - parts.push( - interpolate( - recurrence.display.tokens.every_number_freq, { - 'number': this.interval, - 'freq': recurrence.display.timeintervals_plural[this.freq] - }, true)); - else - parts.push(recurrence.display.frequencies[this.freq]); - - if (this.freq == recurrence.YEARLY) { - if (this.bymonth.length) { - // i.e. 'each january, june' - if (short) - var months = recurrence.display.months_short; - else - var months = recurrence.display.months; - var items = recurrence.array.foreach( - this.bymonth, function(month, i) { - return months[month - 1]; - }); - items = items.join(', '); - parts.push( - interpolate( - recurrence.display.tokens.each, - {'items': items}, true)); - } - - if (this.byday.length || this.bysetpos.length) { - var weekday_items = get_position_weekday(this); - parts.push( - interpolate( - recurrence.display.tokens.on_the_items, - {'items': weekday_items}, true)); - } - } - - if (this.freq == recurrence.MONTHLY) { - if (this.bymonthday.length) { - // i.e. 'on the 1st, 5th, 10th' - var items = recurrence.array.foreach( - this.bymonthday, function(day, i) { - var dt = new Date(); - dt.setMonth(0); - dt.setDate(day); - return recurrence.date.format(dt, recurrence.display.month_day); - }); - items = items.join(', '); - parts.push( - interpolate( - recurrence.display.tokens.on_the_items, - {'items': items}, true)); - - } else if (this.byday.length) { - if (this.byday.length || this.bysetpos.length) { - var weekday_items = get_position_weekday(this); - parts.push( - interpolate( - recurrence.display.tokens.on_the_items, - {'items': weekday_items}, true)); - } - } - } - - if (this.freq == recurrence.WEEKLY) { - if (this.byday.length) { - // i.e. 'each tuesday, wednesday' - var items = recurrence.array.foreach( - this.byday, function(byday) { - var weekday_number = recurrence.to_weekday(byday).number; - if (short) - var weekday = recurrence.display.weekdays_short[ - weekday_number]; - else - var weekday = recurrence.display.weekdays[ - weekday_number]; - return weekday; - }); - items = items.join(', '); - parts.push( - interpolate( - recurrence.display.tokens.each, - {'items': items}, true)); - } - } - - // daily frequencies has no additional formatting, - // hour/minute/second formatting not supported. - - if (this.count) { - if (this.count == 1) - parts.push( - interpolate( - recurrence.display.tokens.count, - {'number': this.count}, true)); - else - parts.push( - interpolate( - recurrence.display.tokens.count_plural, - {'number': this.count}, true)); - } else if (this.until) { - parts.push( - interpolate( - recurrence.display.tokens.until, - {'date': recurrence.date.format(this.until, pgettext('Until date format', '%Y-%m-%d'))}, true)); - } - - return parts.join(', '); - } -}; - - -recurrence.Recurrence = function(options) { - this.init(options); -}; -recurrence.Recurrence.prototype = { - init: function(options) { - options = options || {}; - this.dtstart = options.dtstart || null; - this.dtend = options.dtend || null; - this.rrules = recurrence.array.from(options.rrules || []); - this.exrules = recurrence.array.from(options.exrules || []); - this.rdates = recurrence.array.from(options.rdates || []); - this.exdates = recurrence.array.from(options.exdates || []); - }, - - copy: function() { - return new recurrence.Recurrence({ - 'rrules': recurrence.array.foreach( - this.rrules, function(item) {return item.copy();}), - 'exrules': recurrence.array.foreach( - this.exrules, function(item) {return item.copy();}), - 'rdates': recurrence.array.foreach( - this.rdates, function(item) {return item.copy();}), - 'exdates': recurrence.array.foreach( - this.exdates, function(item) {return item.copy();}) - }); - }, - - serialize: function() { - return recurrence.serialize(this); - } -}; - - -recurrence.Weekday = function(number, index) { - this.init(number, index); -}; -recurrence.Weekday.prototype = { - init: function(number, index) { - this.number = number; - this.index = index || null; - }, - - with_index: function(index) { - if (index == this.index) - return this; - else - return new recurrence.Weekday(this.number, index); - }, - - equals: function(other) { - if (this.number == other.number && this.index == other.index) - return True; - else - return False; - }, - - toString: function() { - if (this.index) - return this.index + recurrence.weekdays[this.number]; - else - return recurrence.weekdays[this.number]; - } -}; - - -recurrence.DateFormat = function(date) { - this.init(date); -}; -recurrence.DateFormat.prototype = { - init: function(date) { - this.data = date; - }, - - format: function(format) { - var tokens = format.match(recurrence.DateFormat.formatchars); - recurrence.array.foreach(tokens, function(token) { - if (this[token.charAt(1)]) - format = format.replace(token, this[token.charAt(1)]()); - }, this); - return format; - }, - - a: function() { - if (this.data.getHours() > 11) - return recurrence.display.ampm.am; - else - return recurrence.display.ampm.pm; - }, - - A: function() { - if (this.data.getHours() > 11) - return recurrence.display.ampm.AM; - else - return recurrence.display.ampm.PM; - }, - - f: function() { - if (this.data.getMinutes() == 0) - return this.g(); - else - return [this.g(), this.i()].join(':'); - }, - - g: function() { - if (this.data.getHours() == 0) - return 12; - else - return this.data.getHours() - 12; - return this.data.getHours(); - }, - - G: function() { - return this.data.getHours(); - }, - - h: function() { - return recurrence.string.rjust(String(this.g()), 2, '0'); - }, - - H: function() { - return recurrence.string.rjust(String(this.G()), 2, '0'); - }, - - i: function() { - return recurrence.string.rjust(String(this.data.getMinutes()), 2, '0'); - }, - - P: function() { - if (this.data.getMinutes() == 0 && this.data.getHours() == 0) - return recurrence.display.tokens.midnight; - if (this.data.getMinutes() == 0 && this.data.getHours() == 12) - return recurrence.display.tokens.noon; - }, - - s: function() { - return recurrence.string.rjust(String(this.data.getSeconds()), 2, '0'); - }, - - Y: function() { - return this.data.getFullYear(); - }, - - b: function() { - return recurrence.display.months_short[this.data.getMonth()]; - }, - - d: function() { - return recurrence.string.rjust(String(this.data.getDate()), 2, '0'); - }, - - D: function() { - return recurrence.display.weekdays_short[ - recurrence.date.weekday(this.data)]; - }, - - F: function() { - return recurrence.display.months[this.data.getMonth()]; - }, - - I: function() { - var now = new Date(); - var date1 = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0); - var date2 = new Date(now.getFullYear(), 6, 1, 0, 0, 0, 0); - var temp = date1.toGMTString(); - var date3 = new Date(temp.substring(0, temp.lastIndexOf(' ')-1)); - var temp = date2.toGMTString(); - var date4 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); - var hours_diff_standard_time = (date1 - date3) / (1000 * 60 * 60); - var hours_diff_daylight_time = (date2 - date4) / (1000 * 60 * 60); - if (hours_diff_daylight_time == hours_diff_standard_time) - return '0'; - else - return '1'; - }, - - j: function() { - return this.data.getDate(); - }, - - l: function() { - return recurrence.display.weekdays[ - recurrence.date.weekday(this.data)]; - }, - - L: function() { - return recurrence.date.isleap(this.data); - }, - - m: function() { - return recurrence.string.rjust( - String(this.data.getMonth() + 1), 2, '0'); - }, - - M: function() { - return recurrence.display.months_short[this.data.getMonth()]; - }, - - n: function() { - return this.data.getMonth() + 1; - }, - - N: function() { - return recurrence.display.months_ap[this.data.getMonth()]; - }, - - O: function() { - var seconds = this.Z(); - return ( - '+' + - recurrence.string.rjust( - String(Math.floor(seconds / 3600)), 2, '0') + - recurrence.string.rjust( - String(Math.floor((seconds / 60) % 60)), 2, '0')); - }, - - r: function() { - return recurrence.date.format(this, '%D, %j %M %Y %H:%i:%s %O'); - }, - - S: function() { - var day = this.data.getDate(); - var ordinal_indicator = recurrence.display.ordinal_indicator; - var language_code = recurrence.language_code; - if (language_code in ordinal_indicator) - return ordinal_indicator[language_code](day); - return ''; - }, - - t: function() { - var month = this.data.getMonth() - var ndays = - recurrence.DateFormat.mdays[month] + - (month == recurrence.FEBRUARY && this.L()); - return recurrence.string.rjust(String(ndays), 2, '0'); - }, - - T: function() { - var tzname = String(this.data).match(/\([^\)]+\)/g).slice(1, -1); - if (!tzname) - tzname = recurrence.date.format(this, '%O'); - return tzname; - }, - - U: function() { - return this.data.getTime(); - }, - - w: function() { - return recurrence.date.weekday(this.data.weekday); - }, - - W: function() { - var week_number = null; - var jan1_weekday = new Date( - this.data.getFullYear(), this.data.getMonth(), 1); - var weekday = this.data.getDay(); - var day_of_year = self.z(); - var prev_year = new Date(this.data.getFullYear() - 1, 0, 1); - if (day_of_year <= (8 - jan1_weekday) && jan1_weekday > 4) { - if (jan1_weekday == 5 || - (jan1_weekday == 6 && recurrence.date.isleap(prev_year))) - week_number = 53; - else - week_number = 52; - } else { - if (recurrence.date.isleap(this.data)) - var i = 366; - else - var i = 365; - if ((i - day_of_year) < (4 - weekday)) { - week_number = 1; - } else { - var j = day_of_year + (7 - weekday) + (jan1_weekday - 1); - week_number = Math.floor(j / 7); - if (jan1_weekday > 4) - week_number = week_number - 1; - } - } - return week_number; - }, - - y: function() { - return String(this.data.getFullYear()).slice(2); - }, - - Y: function() { - return this.data.getFullYear(); - }, - - z: function() { - var doy = recurrence.DateFormat.year_days[this.data.getMonth()] + - this.data.getDate(); - if (this.L() && this.data.getMonth() > 2) - doy += 1; - return doy; - }, - - Z: function() { - var offset = this.data.getTimezoneOffset(); - return offset * 60; - } -}; -recurrence.DateFormat.formatchars = RegExp( - '%[aAbBdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ]', 'g'); -recurrence.DateFormat.year_days = [ - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; -recurrence.DateFormat.mdays = [ - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - - -recurrence.to_weekday = function(token) { - if (token.number && token.index) { - return new recurrence.Weekday(token.number, token.index); - } else if (String(token).match(/[^0-9\-]/g)) { - var token = String(token); - var constant = token.slice(-2, token.length); - var nth = token.slice(0, -2); - if (nth.match(/[^0-9\-]/g)) - throw Error('Invalid weekday token.'); - var weekday = recurrence.weekdays.indexOf(constant); - if (weekday < 0) - throw Error('Invalid weekday token.'); - else - return new recurrence.Weekday(weekday, nth || null); - } else { - return new recurrence.Weekday(parseInt(token, 10)); - } - throw Error('Invalid weekday token.'); -}; - - -recurrence.serialize = function(rule_or_recurrence) { - var serialize_dt = function(dt) { - var pad = function(initial, length) { - initial = String(initial) - var offset = length - initial.length; - if (offset < 0) { - return initial; - } else { - while (initial.length < length) { - initial = '0' + initial; - } - return initial; - } - }; - return pad(dt.getUTCFullYear(), 4) + - pad(dt.getUTCMonth() + 1, 2) + - pad(dt.getUTCDate(), 2) + 'T' + - pad(dt.getUTCHours(), 2) + - pad(dt.getUTCMinutes(), 2) + - pad(dt.getUTCSeconds(), 2) + 'Z'; - }; - - var serialize_rule = function(rule) { - var map_to_string = function(sequence) { - var new_sequence = []; - recurrence.array.foreach(sequence, function(item) { - new_sequence.push(String(item)); - }); - return new_sequence; - }; - - var map_to_param = function(sequence) { - var new_sequence = []; - recurrence.array.foreach(sequence, function(item) { - new_sequence.push(item[0] + '=' + item[1].join(',')); - }); - return new_sequence; - }; - - var values = []; - - values.push(['FREQ', [recurrence.frequencies[rule.freq]]]); - if (rule.interval != 1) - values.push(['INTERVAL', [String(rule.interval)]]); - if (rule.wkst) - values.push(['WKST', [recurrence.weekdays[rule.wkst]]]); - if (rule.count != null) - values.push(['COUNT', [String(rule.count)]]); - else if (rule.until != null) - values.push(['UNTIL', [serialize_dt(rule.until)]]); - if (rule.byday.length) { - var days = recurrence.array.foreach(rule.byday, function(item) { - return recurrence.to_weekday(item).toString(); - }); - values.push(['BYDAY', days]); - } - recurrence.array.foreach(recurrence.byparams, function(param) { - if (param != 'byday') { - var value_list = rule[param] || []; - if (value_list.length) - values.push([param.toUpperCase(), map_to_string(value_list)]); - } - }); - return map_to_param(values).join(';'); - }; - - var map_to_property = function(sequence) { - var new_sequence = recurrence.array.foreach( - sequence, function(item) { - return item.join(':'); - }); - return new_sequence; - }; - - var obj = rule_or_recurrence; - if (obj.freq) - obj = new recurrence.Recurrence({'rrules': [obj]}); - - var items = []; - - if (obj.dtstart) - items.push(['DTSTART', serialize_dt(obj.dtstart)]); - if (obj.dtend) - items.push(['DTEND', serialize_dt(obj.dtend)]); - - recurrence.array.foreach( - obj.rrules, function(item) { - items.push(['RRULE', serialize_rule(item)]); - }); - recurrence.array.foreach( - obj.exrules, function(item) { - items.push(['EXRULE', serialize_rule(item)]); - }); - recurrence.array.foreach( - obj.rdates, function(item) { - items.push(['RDATE', serialize_dt(item)]); - }); - recurrence.array.foreach( - obj.exdates, function(item) { - items.push(['EXDATE', serialize_dt(item)]); - }); - - return map_to_property(items).join('\n'); -}; - - -recurrence.deserialize = function(text) { - var deserialize_dt = function(text) { - var year = parseInt(text.slice(0, 4), 10); - var month = parseInt(text.slice(4, 6), 10); - var day = parseInt(text.slice(6, 8), 10); - if (text.indexOf('T') > 0) { - var hour = parseInt(text.slice(9, 11), 10); - var minute = parseInt(text.slice(11, 13), 10); - var second = parseInt(text.slice(13, 15), 10); - } else { - var hour = 0; - var minute = 0; - var second = 0; - } - var dt = new Date(); - if (text.indexOf('Z') > 0) { - dt.setUTCFullYear(year); - dt.setUTCMonth(month - 1); - dt.setUTCDate(day); - dt.setUTCHours(hour); - dt.setUTCMinutes(minute); - dt.setUTCSeconds(second); - } else { - dt.setFullYear(year); - dt.setMonth(month - 1); - dt.setDate(day); - dt.setHours(hour); - dt.setMinutes(minute); - dt.setSeconds(second); - } - return dt; - }; - - var dtstart = null; - var dtend = null; - var rrules = []; - var exrules = []; - var rdates = []; - var exdates = []; - - var pattern = /(DTSTART|DTEND|RRULE|EXRULE|RDATE|EXDATE)[^:]*:(.*)/g; - var tokens = text.match(pattern) || []; - - recurrence.array.foreach( - tokens, function(token) { - var label = token.split(':', 2)[0]; - var param_text = token.split(':', 2)[1]; - - if (param_text.indexOf('=') < 0) { - var params = param_text; - } else { - var param_tokens = param_text.split(';'); - var params = recurrence.array.foreach( - param_tokens, function(item) { - var param_name = recurrence.string.strip( - item.split('=', 2)[0]); - var param_value = recurrence.string.strip( - item.split('=', 2)[1]); - var value_list = param_value.split(','); - var value_list = recurrence.array.foreach( - param_value.split(','), function(item) { - return recurrence.string.strip(item); - }); - return [param_name, value_list]; - }); - } - - if (label == 'RRULE' || label == 'EXRULE') { - var freq = 0; - var options = {}; - recurrence.array.foreach( - params, function(item) { - var key = item[0]; - var param = key.toLowerCase(); - var value = item[1]; - - if (key == 'FREQ') { - if (recurrence.frequencies.indexOf(value[0]) != -1) { - freq = recurrence.frequencies.indexOf(value[0]); - } - } else if (key == 'INTERVAL') { - options[param] = parseInt(value[0], 10); - } else if (key == 'WKST') { - options[param] = recurrence.to_weekday(value[0]); - } else if (key == 'COUNT') { - options[param] = parseInt(value[0], 10); - } else if (key == 'UNTIL') { - options[param] = deserialize_dt(value[0]); - } else if (key == 'BYDAY') { - options[param] = recurrence.array.foreach( - value, function(item) { - return recurrence.to_weekday(item); - }); - } else { - options[param] = recurrence.array.foreach( - value, function(item) { - return parseInt(item, 10); - }); - } - }); - if (label == 'RRULE') - rrules.push(new recurrence.Rule(freq, options)); - else - exrules.push(new recurrence.Rule(freq, options)); - - } else if (label == 'DTSTART') { - dtstart = deserialize_dt(params); - } else if (label == 'DTEND') { - dtend = deserialize_dt(params); - } else if (label == 'RDATE') { - rdates.push(deserialize_dt(params)); - } else if (label == 'EXDATE') { - exdates.push(deserialize_dt(params)); - } - }); - - return new recurrence.Recurrence({ - 'dtstart': dtstart, 'dtend': dtend, - 'rrules': rrules, 'exrules': exrules, - 'rdates': rdates, 'exdates': exdates - }); -}; - - -recurrence.log = function(message) { - var dom = document.createElement('div'); - dom.innerHTML = message; - document.body.insertBefore(dom, document.body.firstChild); -}; - - -recurrence.string = { - format: function(string, map) { - for (var key in map) - string = string.replace(RegExp('%' + key, 'g'), map[key]); - return string - }, - - capitalize: function(string) { - return ( - string.charAt(0).toUpperCase() + - string.slice(1, string.length)); - }, - - strip: function(string) { - return string.replace( - /^[ \t\n\r]*/, '').replace(/[ \t\n\r]*$/, ''); - }, - - rjust: function(string, length, character) { - var initial = String(string); - var offset = length - initial.length; - character = character || ' '; - if (offset < 0) { - return initial; - } else { - while (initial.length < length) { - initial = character.charAt(0) + initial; - } - return initial; - } - }, - - ljust: function(string, length, character) { - var initial = String(string); - var offset = length - initial.length; - character = character || ' '; - if (offset < 0) { - return initial; - } else { - while (initial.length < length) { - initial = initial + character[0]; - } - return initial; - } - } -}; - - -recurrence.date = { - format: function(date, format) { - return new recurrence.DateFormat(date).format(format); - }, - - isleap: function(date) { - var year = date.getFullYear(); - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); - }, - - weekday: function(date) { - var day = date.getDay() - 1; - if (day < 0) - day = day + 7; - else if (day > 6) - day = day - 7; - return day; - }, - - days_in_month: function(date) { - var m = date.getMonth() + 1; - var y = date.getFullYear(); - if (m == 1 || m == 3 || m == 5 || m == 7 || - m == 8 || m == 10 || m == 12) - return 31; - else if (m == 4 || m == 6 || m == 9 || m == 11) - return 30; - else if (m == 2 && recurrence.date.isleap(date)) - return 29; - else - return 28; - } -}; - - -recurrence.array = { - foreach: function(array, func, bindto) { - if (bindto) - func = recurrence.func.bind(func, bindto); - array = recurrence.array.from(array); - var return_values = []; - for (var i=0; i < array.length; i++) - return_values.push(func(array[i], i)); - return return_values; - }, - - from: function(iterable) { - if (!iterable) - return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i=0, length=iterable.length; i < length; i++) - results.push(iterable[i]); - return results; - } - }, - - remove: function(array, item) { - array.splice(array.indexOf(item), 1); - } -}; - - -recurrence.func = { - bind: function() { - var args = recurrence.array.from(arguments); - var func = args.shift(); - var object = args.shift(); - return function() { - return func.apply( - object, args.concat(recurrence.array.from(arguments))); - } - } -}; - - -if (!Array.indexOf) { - // ie doesn't have indexOf on arrays - Array.prototype.indexOf = function(obj) { - for (var i=0; i < this.length; i++) - if (this[i] == obj) - return i; - return -1; - }; -} - - -// frequencies -recurrence.YEARLY = 0; -recurrence.MONTHLY = 1; -recurrence.WEEKLY = 2; -recurrence.DAILY = 3; -recurrence.HOURLY = 4; -recurrence.MINUTELY = 5; -recurrence.SECONDLY = 6; - -// months -recurrence.JANUARY = 1; -recurrence.FEBRUARY = 2; -recurrence.MARCH = 3; -recurrence.APRIL = 4; -recurrence.MAY = 5; -recurrence.JUNE = 6; -recurrence.JULY = 7; -recurrence.AUGUST = 8; -recurrence.SEPTEMBER = 9; -recurrence.OCTOBER = 10; -recurrence.NOVEMBER = 11; -recurrence.DECEMBER = 12; - -// weekdays -recurrence.MONDAY = recurrence.MO = new recurrence.Weekday(0, null); -recurrence.TUEDSAY = recurrence.TU = new recurrence.Weekday(1, null); -recurrence.WEDNESDAY = recurrence.WE = new recurrence.Weekday(2, null); -recurrence.THURSDAY = recurrence.TH = new recurrence.Weekday(3, null); -recurrence.FRIDAY = recurrence.FR = new recurrence.Weekday(4, null); -recurrence.SATURDAY = recurrence.SA = new recurrence.Weekday(5, null); -recurrence.SUNDAY = recurrence.SU = new recurrence.Weekday(6, null); - -// enumerations -recurrence.byparams = [ - 'bysetpos', 'bymonth', 'bymonthday', 'byyearday', - 'byweekno', 'byday', 'byhour', 'byminute', 'bysecond' -]; -recurrence.frequencies = [ - 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', - 'HOURLY', 'MINUTELY', 'SECONDLY' -]; -recurrence.weekdays = [ - 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU' -]; -// recurrence.firstweekday = 0; - - -// i18n no-ops if jsi18n not loaded - -if (typeof(catalog) === 'undefined') { - var catalog = []; -} else { - var catalog = catalog; -} - -var gettext = gettext || function(msgid) { - var value = catalog[msgid]; - if (typeof(value) == 'undefined') { - return msgid; - } else { - return (typeof(value) == 'string') ? value : value[0]; - } -}; - -var interpolate = interpolate || function(fmt, obj, named) { - if (named) { - return fmt.replace(/%\(\w+\)s/g, function(match) { - return String(obj[match.slice(2,-2)]) - }); - } else { - return fmt.replace(/%s/g, function(match) { - return String(obj.shift()) - }); - } -}; - - -// display - -if (!recurrence.display) - recurrence.display = {}; - -recurrence.display.tokens = { - 'midnight': gettext('midnight'), - 'noon': gettext('noon'), - 'on_the_items': gettext('on the %(items)s'), - 'every_number_freq': gettext('every %(number)s %(freq)s'), - 'each': gettext('each %(items)s'), - 'count': gettext('occuring %(number)s time'), - 'count_plural': gettext('occuring %(number)s times'), - 'until': gettext('until %(date)s') -}; - -recurrence.display.timeintervals = [ - gettext('year'), gettext('month'), gettext('week'), gettext('day'), - gettext('hour'), gettext('minute'), gettext('second') -]; -recurrence.display.timeintervals_plural = [ - gettext('years'), gettext('months'), gettext('weeks'), gettext('days'), - gettext('hours'), gettext('minutes'), gettext('seconds') -]; -recurrence.display.frequencies = [ - gettext('annually'), gettext('monthly'), gettext('weekly'), gettext('daily'), - gettext('hourly'), gettext('minutely'), gettext('secondly') -]; -recurrence.display.weekdays = [ - gettext('Monday'), gettext('Tuesday'), gettext('Wednesday'), gettext('Thursday'), - gettext('Friday'), gettext('Saturday'), gettext('Sunday') -]; -recurrence.display.weekdays_short = [ - gettext('Mon'), gettext('Tue'), gettext('Wed'), gettext('Thu'), - gettext('Fri'), gettext('Sat'), gettext('Sun') -]; -recurrence.display.weekdays_oneletter = [ - pgettext('Monday first letter', 'M'), - pgettext('Tuesday first letter', 'T'), - pgettext('Wednesday first letter', 'W'), - pgettext('Thursday first letter', 'T'), - pgettext('Friday first letter', 'F'), - pgettext('Saturday first letter', 'S'), - pgettext('Sunday first letter', 'S') -]; -recurrence.display.weekdays_position = { - '1': gettext('first %(weekday)s'), - '2': gettext('second %(weekday)s'), - '3': gettext('third %(weekday)s'), - '4': gettext('fourth %(weekday)s'), - '-1': gettext('last %(weekday)s'), - '-2': gettext('second last %(weekday)s'), - '-3': gettext('third last %(weekday)s') -}; -recurrence.display.weekdays_position_short = { - '1': gettext('1st %(weekday)s'), - '2': gettext('2nd %(weekday)s'), - '3': gettext('3rd %(weekday)s'), - '4': gettext('4th %(weekday)s'), - '-1': gettext('last %(weekday)s'), - '-2': gettext('2nd last %(weekday)s'), - '-3': gettext('3rd last %(weekday)s') -}; -recurrence.display.months = [ - gettext('January'), gettext('February'), gettext('March'), - gettext('April'), pgettext('month name', 'May'), gettext('June'), - gettext('July'), gettext('August'), gettext('September'), - gettext('October'), gettext('November'), gettext('December') -]; -recurrence.display.months_short = [ - gettext('Jan'), gettext('Feb'), gettext('Mar'), - gettext('Apr'), pgettext('month name', 'May'), gettext('Jun'), - gettext('Jul'), gettext('Aug'), gettext('Sep'), - gettext('Oct'), gettext('Nov'), gettext('Dec') -]; -recurrence.display.months_ap = [ - gettext('Jan.'), gettext('Feb.'), gettext('March'), - gettext('April'), pgettext('month name', 'May'), gettext('June'), - gettext('July'), gettext('Aug.'), gettext('Sept.'), - gettext('Oct.'), gettext('Nov.'), gettext('Dec.') -]; -recurrence.display.ampm = { - 'am': gettext('a.m.'), 'pm': gettext('p.m.'), - 'AM': gettext('AM'), 'PM': gettext('PM') -}; -recurrence.display.month_day = pgettext('Day of month', '%j%S'); - -recurrence.display.ordinal_indicator = { - 'en-us': function(day) { - if (day == 11 || day == 12 || day == 13) - return 'th'; - var last = day % 10; - if (last == 1) - return 'st'; - if (last == 2) - return 'nd'; - if (last == 3) - return 'rd'; - return 'th'; - }, - 'fr-FR': function(day) { - if (day == 1) - return 'er'; - return ''; - } -}; |