Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
753 lines
21 KiB
JavaScript
Executable file
753 lines
21 KiB
JavaScript
Executable file
define(function(require, exports, module) {
|
|
'use strict';
|
|
|
|
var AlarmTemplate = require('templates/alarm');
|
|
var EventBase = require('./event_base');
|
|
var InputParser = require('shared/input_parser');
|
|
var IntlHelper = require('shared/intl_helper');
|
|
var QueryString = require('querystring');
|
|
var co = require('ext/co');
|
|
var core = require('core');
|
|
var localCalendarId = require('common/constants').localCalendarId;
|
|
var notification = require('notification');
|
|
var router = require('router');
|
|
var viewFactory = require('./factory');
|
|
|
|
require('dom!modify-event-view');
|
|
|
|
IntlHelper.define('formalDate', 'datetime', {
|
|
month: '2-digit',
|
|
year: '2-digit',
|
|
day: '2-digit'
|
|
});
|
|
|
|
IntlHelper.define('shortTime', 'datetime', {
|
|
hour: 'numeric',
|
|
minute: 'numeric'
|
|
});
|
|
|
|
function ModifyEvent(options) {
|
|
this.deleteRecord = this.deleteRecord.bind(this);
|
|
this._toggleAllDay = this._toggleAllDay.bind(this);
|
|
EventBase.apply(this, arguments);
|
|
}
|
|
module.exports = ModifyEvent;
|
|
|
|
ModifyEvent.prototype = {
|
|
__proto__: EventBase.prototype,
|
|
|
|
ERROR_PREFIX: 'event-error-',
|
|
|
|
MAX_ALARMS: 5,
|
|
|
|
formats: {
|
|
date: 'formalDate',
|
|
time: 'shortTime',
|
|
},
|
|
|
|
selectors: {
|
|
element: '#modify-event-view',
|
|
alarmList: '#modify-event-view .alarms',
|
|
form: '#modify-event-view form',
|
|
startTimeLocale: '#start-time-locale',
|
|
endDateLocale: '#end-date-locale',
|
|
endTimeLocale: '#end-time-locale',
|
|
status: '#modify-event-view section[role="status"]',
|
|
errors: '#modify-event-view .errors',
|
|
primaryButton: '#modify-event-view .save',
|
|
deleteButton: '#modify-event-view .delete-record',
|
|
header: '#modify-event-header'
|
|
},
|
|
|
|
uiSelector: '[name="%"]',
|
|
|
|
_duration: 0, // The duration between start and end dates.
|
|
|
|
_initEvents: function() {
|
|
EventBase.prototype._initEvents.apply(this, arguments);
|
|
|
|
this.deleteButton.addEventListener('click', this.deleteRecord);
|
|
this.form.addEventListener('click', this.focusHandler);
|
|
this.form.addEventListener('submit', this.primary);
|
|
this.form.addEventListener('input', this._toggleSave.bind(this));
|
|
|
|
var allday = this.getEl('allday');
|
|
allday.addEventListener('change', this._toggleAllDay);
|
|
|
|
this.alarmList.addEventListener('change', this._changeAlarm.bind(this));
|
|
},
|
|
|
|
/**
|
|
* Fired when the allday checkbox changes.
|
|
*/
|
|
_toggleAllDay: function(e) {
|
|
var allday = this.getEl('allday').checked;
|
|
|
|
if (allday) {
|
|
// enable case
|
|
this.element.classList.add(this.ALLDAY);
|
|
} else {
|
|
// disable case
|
|
this.element.classList.remove(this.ALLDAY);
|
|
if (e) {
|
|
// only reset the start/end time if coming from an user interaction
|
|
this._resetDateTime();
|
|
}
|
|
}
|
|
|
|
// because of race conditions it is theoretically possible
|
|
// for the user to check/uncheck this value
|
|
// when we don't actually have a model loaded.
|
|
if (this.event) {
|
|
this.event.isAllDay = !!allday;
|
|
}
|
|
|
|
// Reset alarms if we come from a user event
|
|
if (e) {
|
|
this.event.alarms = [];
|
|
this.updateAlarms(allday);
|
|
}
|
|
},
|
|
|
|
_resetDateTime: function() {
|
|
// if start event was "all day" and switch to regular event start/end time
|
|
// will be the same, so we reset to default start time, otherwise we keep
|
|
// the previously selected value
|
|
var startDateTime = this._getStartDateTime();
|
|
if (startDateTime === this._getEndDateTime()) {
|
|
var startDate = new Date(startDateTime);
|
|
this._setDefaultHour(startDate);
|
|
this.getEl('startTime').value = InputParser.exportTime(startDate);
|
|
this._renderDateTimeLocale(
|
|
this._findElement('startTimeLocale'), startDate);
|
|
// default event duration is 1 hour
|
|
this._duration = 60 * 60 * 1000;
|
|
this._setEndDateTimeWithCurrentDuration();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called when any alarm is changed
|
|
*/
|
|
_changeAlarm: function(e) {
|
|
var template = AlarmTemplate;
|
|
if (e.target.value == 'none') {
|
|
var parent = e.target.parentNode;
|
|
parent.parentNode.removeChild(parent);
|
|
return;
|
|
}
|
|
|
|
// Append a new alarm select only if we don't have an empty one or if we
|
|
// didn't reach the maximum number of alarms
|
|
var alarms = this.queryAlarms();
|
|
if (alarms.length >= this.MAX_ALARMS ||
|
|
alarms.some(el => el.value === 'none')) {
|
|
return;
|
|
}
|
|
|
|
var newAlarm = document.createElement('div');
|
|
newAlarm.innerHTML = template.picker.render({
|
|
layout: this.event.isAllDay ? 'allday' : 'standard'
|
|
});
|
|
this.alarmList.appendChild(newAlarm);
|
|
},
|
|
|
|
/**
|
|
* Check if current event has been stored in the database
|
|
*/
|
|
isSaved: function() {
|
|
return this.element.classList.contains(this.UPDATE);
|
|
},
|
|
|
|
/**
|
|
* Build the initial list of calendar ids.
|
|
*/
|
|
onfirstseen: function() {
|
|
// we need to notify users (specially automation tests) somehow that the
|
|
// options are still being loaded from DB, this is very important to
|
|
// avoid race conditions (eg. trying to set calendar before list is
|
|
// built) notice that we also add the class to the markup because on some
|
|
// really rare occasions "onfirstseen" is called after the EventBase
|
|
// removed the "loading" class from the root element (seen it happen less
|
|
// than 1% of the time)
|
|
this.getEl('calendarId').classList.add(this.LOADING);
|
|
},
|
|
|
|
_renderCalendars: function(records) {
|
|
// remove old calendars (this will be called every time we have a change on
|
|
// any calendar)
|
|
var select = this.getEl('calendarId');
|
|
// remove all the options
|
|
select.options.length = 0;
|
|
select.classList.remove(this.LOADING);
|
|
|
|
records
|
|
.filter(r => r.capabilities.canCreateEvent)
|
|
.forEach(record => {
|
|
var id = record.calendar._id;
|
|
var {name} = record.calendar.remote;
|
|
var option = document.createElement('option');
|
|
|
|
if (id === localCalendarId) {
|
|
option.text = navigator.mozL10n.get('calendar-local');
|
|
option.setAttribute('data-l10n-id', 'calendar-local');
|
|
} else {
|
|
option.text = name;
|
|
}
|
|
|
|
option.value = id;
|
|
select.add(option);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Mark all field's readOnly flag.
|
|
*
|
|
* @param {Boolean} boolean true/false.
|
|
*/
|
|
_markReadonly: function(boolean) {
|
|
var i = 0;
|
|
var fields = this.form.querySelectorAll('[name]');
|
|
var len = fields.length;
|
|
|
|
for (; i < len; i++) {
|
|
fields[i].readOnly = boolean;
|
|
}
|
|
},
|
|
|
|
queryAlarms: function() {
|
|
return Array.from(document.querySelectorAll('[name="alarm[]"]'));
|
|
},
|
|
|
|
get alarmList() {
|
|
return this._findElement('alarmList');
|
|
},
|
|
|
|
get form() {
|
|
return this._findElement('form');
|
|
},
|
|
|
|
get deleteButton() {
|
|
return this._findElement('deleteButton');
|
|
},
|
|
|
|
get fieldRoot() {
|
|
return this.form;
|
|
},
|
|
|
|
/**
|
|
* Ask the provider to persist an event:
|
|
*
|
|
* 1. update the model with form data
|
|
*
|
|
* 2. send it to the provider if it has the capability
|
|
*
|
|
* 3. set the position of the calendar to startDate of new/edited event.
|
|
*
|
|
* 4. redirect to last view.
|
|
*
|
|
* For now both update & create share the same
|
|
* behaviour (redirect) in the future we may change this.
|
|
*/
|
|
_persistEvent: co.wrap(function *(method) {
|
|
// create model data
|
|
var data = this.formData();
|
|
var errors;
|
|
|
|
// we check explicitly for true, because the alternative
|
|
// is an error object.
|
|
if ((errors = this.event.updateAttributes(data)) !== true) {
|
|
this.showErrors(errors);
|
|
return;
|
|
}
|
|
|
|
// can't create without a calendar id
|
|
// because of defaults this should be impossible.
|
|
if (!data.calendarId) {
|
|
return;
|
|
}
|
|
|
|
// mark view as 'in progress' so we can style
|
|
// it via css during that time period
|
|
this.element.classList.add(this.PROGRESS);
|
|
|
|
try {
|
|
// need to store date before async operation (event might change)
|
|
var moveDate = this.event.startDate;
|
|
yield core.bridge[method](this.event);
|
|
// move the position in the calendar to the added/edited day
|
|
core.timeController.move(moveDate);
|
|
// order is important the above method triggers the building
|
|
// of the dom elements so selectedDay must come after.
|
|
core.timeController.selectedDay = moveDate;
|
|
this._navigateAfterPersist(method, moveDate);
|
|
} catch(err) {
|
|
this.showErrors(err);
|
|
}
|
|
|
|
this.element.classList.remove(this.PROGRESS);
|
|
}),
|
|
|
|
_navigateAfterPersist: function(method, moveDate) {
|
|
// we pass the date so we are able to scroll to the event on the
|
|
// day/week views
|
|
var state = {
|
|
eventStartHour: moveDate.getHours()
|
|
};
|
|
|
|
if (method === 'updateEvent') {
|
|
// If we edit a view our history stack looks like:
|
|
// /week -> /event/view -> /event/save -> /event/view
|
|
// We need to return all the way to the top of the stack
|
|
// We can remove this once we have a history stack
|
|
viewFactory.get('ViewEvent', v => router.go(v.returnTop(), state));
|
|
return;
|
|
}
|
|
|
|
router.go(this.returnTo(), state);
|
|
},
|
|
|
|
/**
|
|
* Deletes current record if provider is present and has the capability.
|
|
*/
|
|
deleteRecord: co.wrap(function *(event) {
|
|
if (event) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
if (!this.isSaved()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
yield notification.revokeNotificationsForEvent(this.event);
|
|
yield core.bridge.deleteEvent(this.event);
|
|
// If we edit a view our history stack looks like:
|
|
// /week -> /event/view -> /event/save -> /event/view
|
|
// We need to return all the way to the top of the stack
|
|
// We can remove this once we have a history stack
|
|
viewFactory.get('ViewEvent', view => router.go(view.returnTop()));
|
|
} catch (err) {
|
|
this.showErrors(err);
|
|
}
|
|
}),
|
|
|
|
/**
|
|
* Persist current model.
|
|
*/
|
|
primary: function(event) {
|
|
if (event) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
// Disable the button on primary event to avoid race conditions
|
|
this.disablePrimary();
|
|
|
|
if (this.isSaved()) {
|
|
this._persistEvent('updateEvent');
|
|
} else {
|
|
this._persistEvent('createEvent');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Enlarges focus areas for .button controls
|
|
*/
|
|
focusHandler: function(e) {
|
|
var input = e.target.querySelector('input, select');
|
|
if (input && e.target.classList.contains('button')) {
|
|
input.focus();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Export form information into a format
|
|
* the model can understand.
|
|
*
|
|
* @return {Object} formatted data suitable
|
|
* for use with Calendar.Model.Event.
|
|
*/
|
|
formData: function() {
|
|
var fields = {
|
|
title: this.getEl('title').value,
|
|
location: this.getEl('location').value,
|
|
description: this.getEl('description').value,
|
|
calendarId: this.getEl('calendarId').value
|
|
};
|
|
|
|
var startTime;
|
|
var endTime;
|
|
var allday = this.getEl('allday').checked;
|
|
|
|
if (allday) {
|
|
startTime = null;
|
|
endTime = null;
|
|
} else {
|
|
startTime = this.getEl('startTime').value;
|
|
endTime = this.getEl('endTime').value;
|
|
}
|
|
|
|
fields.startDate = InputParser.formatInputDate(
|
|
this.getEl('startDate').value,
|
|
startTime
|
|
);
|
|
|
|
fields.endDate = InputParser.formatInputDate(
|
|
this.getEl('endDate').value,
|
|
endTime
|
|
);
|
|
|
|
// Yahoo uses the same start and end date & time for all day events.
|
|
// In order to distinguish all-day event from Yahoo calendar and event
|
|
// with 0 duration we set duration of the event starting and ending at
|
|
// the same date and time to 1 millisecond.
|
|
if (!allday && fields.endDate.getTime() === fields.startDate.getTime()) {
|
|
fields.endDate.setTime(
|
|
fields.startDate.getTime() + 1
|
|
);
|
|
}
|
|
|
|
if (allday) {
|
|
// when the event is all day we display the same
|
|
// day that the entire event spans but we must actually
|
|
// end the event at the first second, minute hour of the next
|
|
// day. This will ensure the server handles it as an all day event.
|
|
fields.endDate.setDate(
|
|
fields.endDate.getDate() + 1
|
|
);
|
|
}
|
|
|
|
fields.alarms = [];
|
|
var triggers = ['none'];
|
|
this.queryAlarms().forEach(alarm => {
|
|
if (triggers.indexOf(alarm.value) !== -1) {
|
|
return;
|
|
}
|
|
|
|
triggers.push(alarm.value);
|
|
|
|
fields.alarms.push({
|
|
action: 'DISPLAY',
|
|
trigger: parseInt(alarm.value, 10)
|
|
});
|
|
});
|
|
|
|
return fields;
|
|
},
|
|
|
|
enablePrimary: function() {
|
|
var btn = this.primaryButton;
|
|
btn.removeAttribute('aria-disabled');
|
|
btn.removeAttribute('disabled');
|
|
},
|
|
|
|
disablePrimary: function() {
|
|
var btn = this.primaryButton;
|
|
btn.setAttribute('aria-disabled', 'true');
|
|
btn.setAttribute('disabled', 'disabled');
|
|
},
|
|
|
|
/**
|
|
* Re-enable the primary button when we show errors
|
|
*/
|
|
showErrors: function() {
|
|
this.enablePrimary();
|
|
EventBase.prototype.showErrors.apply(this, arguments);
|
|
},
|
|
|
|
/**
|
|
* Read the urlparams and override stuff on our event model.
|
|
* @param {string} search Optional string of the form ?foo=bar&cat=dog.
|
|
* @private
|
|
*/
|
|
_overrideEvent: function(search) {
|
|
if (!search) {
|
|
var hash = window.location.hash;
|
|
search = hash.split('?')[1];
|
|
}
|
|
|
|
if (!search || search.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// Remove the question mark that begins the search.
|
|
if (search.substr(0, 1) === '?') {
|
|
search = search.substr(1, search.length - 1);
|
|
}
|
|
|
|
var field, value;
|
|
// Parse the urlparams.
|
|
var params = QueryString.parse(search);
|
|
for (field in params) {
|
|
value = params[field];
|
|
switch (field) {
|
|
case ModifyEvent.OverrideableField.START_DATE:
|
|
case ModifyEvent.OverrideableField.END_DATE:
|
|
params[field] = new Date(value);
|
|
break;
|
|
default:
|
|
params[field] = value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Override fields on our event.
|
|
var model = this.event;
|
|
for (field in ModifyEvent.OverrideableField) {
|
|
value = ModifyEvent.OverrideableField[field];
|
|
model[value] = params[value] || model[value];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Updates form to use values from the current model.
|
|
*
|
|
* Does not handle readonly flags or calenarId associations.
|
|
* Suitable for use in pre-populating values for both new and
|
|
* existing events.
|
|
*
|
|
* Resets any value on the current form.
|
|
*/
|
|
_updateUI: function() {
|
|
this._overrideEvent();
|
|
this.form.reset();
|
|
|
|
var model = this.event;
|
|
this.getEl('title').value = model.title;
|
|
this.getEl('location').value = model.location;
|
|
var dateSrc = model;
|
|
if (model.remote.isRecurring && this.busytime) {
|
|
dateSrc = this.busytime;
|
|
}
|
|
|
|
var startDate = dateSrc.startDate;
|
|
var endDate = dateSrc.endDate;
|
|
this._duration = endDate.getTime() - startDate.getTime();
|
|
|
|
// update the allday status of the view
|
|
var allday = this.getEl('allday');
|
|
if (allday && (allday.checked = model.isAllDay)) {
|
|
this._toggleAllDay();
|
|
endDate = this.formatEndDate(endDate);
|
|
}
|
|
|
|
this.getEl('startDate').value = InputParser.exportDate(startDate);
|
|
this._setupDateTimeSync('startDate', 'start-date-locale', startDate);
|
|
|
|
this.getEl('endDate').value = InputParser.exportDate(endDate);
|
|
this._setupDateTimeSync('endDate', 'end-date-locale', endDate);
|
|
|
|
this.getEl('startTime').value = InputParser.exportTime(startDate);
|
|
this._setupDateTimeSync('startTime', 'start-time-locale', startDate);
|
|
|
|
this.getEl('endTime').value = InputParser.exportTime(endDate);
|
|
this._setupDateTimeSync('endTime', 'end-time-locale', endDate);
|
|
|
|
this.getEl('description').textContent = model.description;
|
|
|
|
// update calendar id
|
|
this.getEl('calendarId').value = model.calendarId;
|
|
|
|
// calendar display
|
|
var currentCalendar = this.getEl('currentCalendar');
|
|
|
|
if (this.originalCalendar) {
|
|
currentCalendar.value =
|
|
this.originalCalendar.remote.name;
|
|
|
|
currentCalendar.readOnly = true;
|
|
}
|
|
|
|
this.updateAlarms(model.isAllDay);
|
|
this._toggleSave();
|
|
},
|
|
|
|
_toggleSave: function() {
|
|
var enabled = this.getEl('title').value || this.getEl('location').value;
|
|
if (enabled) {
|
|
this.enablePrimary();
|
|
} else {
|
|
this.disablePrimary();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Handling a layer over <input> to have localized
|
|
* date/time
|
|
*/
|
|
_setupDateTimeSync: function(src, target, value) {
|
|
var targetElement = document.getElementById(target);
|
|
if (!targetElement) {
|
|
return;
|
|
}
|
|
this._renderDateTimeLocale(targetElement, value);
|
|
|
|
var type = targetElement.dataset.type;
|
|
var callback = type === 'date' ?
|
|
this._updateDateLocaleOnInput : this._updateTimeLocaleOnInput;
|
|
|
|
this.getEl(src)
|
|
.addEventListener('input', function(e) {
|
|
callback.call(this, targetElement, e);
|
|
|
|
// We only auto change the end date and end time
|
|
// when user changes start date or start time,
|
|
// or end datetime is before start datetime
|
|
// after changing end date or end time.
|
|
// Otherwise, we don't auto change end date and end time.
|
|
if (targetElement.id === 'start-date-locale' ||
|
|
targetElement.id === 'start-time-locale') {
|
|
this._setEndDateTimeWithCurrentDuration();
|
|
} else if (this._getEndDateTime() < this._getStartDateTime()) {
|
|
this._setEndDateTimeWithCurrentDuration();
|
|
this.showErrors({
|
|
name: type === 'date' ?
|
|
'start-date-after-end-date' :
|
|
'start-time-after-end-time'
|
|
});
|
|
}
|
|
|
|
this._duration = this._getEndDateTime() - this._getStartDateTime();
|
|
}.bind(this));
|
|
},
|
|
|
|
_setEndDateTimeWithCurrentDuration: function() {
|
|
var date = new Date(this._getStartDateTime() + this._duration);
|
|
var endDateLocale = this._findElement('endDateLocale');
|
|
var endTimeLocale = this._findElement('endTimeLocale');
|
|
this.getEl('endDate').value = InputParser.exportDate(date);
|
|
this.getEl('endTime').value = InputParser.exportTime(date);
|
|
this._renderDateTimeLocale(endDateLocale, date);
|
|
this._renderDateTimeLocale(endTimeLocale, date);
|
|
},
|
|
|
|
_getStartDateTime: function() {
|
|
return new Date(this.getEl('startDate').value + 'T' +
|
|
this.getEl('startTime').value).getTime();
|
|
},
|
|
|
|
_getEndDateTime: function() {
|
|
return new Date(this.getEl('endDate').value + 'T' +
|
|
this.getEl('endTime').value).getTime();
|
|
},
|
|
|
|
_renderDateTimeLocale: function(targetElement, value) {
|
|
// we inject the targetElement to make it easier to test
|
|
var type = targetElement.dataset.type;
|
|
var formatName = this.formats[type];
|
|
var formatter = IntlHelper.get(formatName);
|
|
targetElement.textContent = formatter.format(value);
|
|
// we need to store the format and date for l10n
|
|
targetElement.setAttribute('data-l10n-date-format', formatName);
|
|
targetElement.dataset.date = value;
|
|
},
|
|
|
|
_updateDateLocaleOnInput: function(targetElement, e) {
|
|
var selected = InputParser.importDate(e.target.value);
|
|
// use date constructor to avoid issues, see Bug 966516
|
|
var date = new Date(selected.year, selected.month, selected.date);
|
|
this._renderDateTimeLocale(targetElement, date);
|
|
},
|
|
|
|
_updateTimeLocaleOnInput: function(targetElement, e) {
|
|
var selected = InputParser.importTime(e.target.value);
|
|
var date = new Date();
|
|
date.setHours(selected.hours);
|
|
date.setMinutes(selected.minutes);
|
|
date.setSeconds(0);
|
|
this._renderDateTimeLocale(targetElement, date);
|
|
},
|
|
|
|
/**
|
|
* Called on render or when toggling an all-day event
|
|
*/
|
|
updateAlarms: co.wrap(function *(isAllDay) {
|
|
var template = AlarmTemplate;
|
|
var alarms = [];
|
|
|
|
// Used to make sure we don't duplicate alarms
|
|
var alarmMap = {};
|
|
|
|
if (this.event.alarms) {
|
|
//jshint boss:true
|
|
for (var i = 0, alarm; alarm = this.event.alarms[i]; i++) {
|
|
alarmMap[alarm.trigger] = true;
|
|
alarm.layout = isAllDay ? 'allday' : 'standard';
|
|
alarms.push(alarm);
|
|
}
|
|
}
|
|
|
|
var layout = isAllDay ? 'allday' : 'standard';
|
|
var value = yield core.bridge.getSetting(layout + 'AlarmDefault');
|
|
|
|
if (!this.isSaved() && !alarmMap[value] && !this.event.alarms.length) {
|
|
alarms.push({
|
|
layout: layout,
|
|
trigger: value
|
|
});
|
|
}
|
|
|
|
// Bug_898242 to show an event when default is 'none',
|
|
// we check if the event is not saved, if so, we push
|
|
// the default alarm on to the list.
|
|
if ((value === 'none' && this.isSaved()) || value !== 'none') {
|
|
alarms.push({
|
|
layout: layout
|
|
});
|
|
}
|
|
|
|
this.alarmList.innerHTML = template.picker.renderEach(alarms).join('');
|
|
}),
|
|
|
|
reset: function() {
|
|
var list = this.element.classList;
|
|
|
|
list.remove(this.UPDATE);
|
|
list.remove(this.CREATE);
|
|
list.remove(this.READONLY);
|
|
list.remove(this.ALLDAY);
|
|
|
|
var allday = this.getEl('allday');
|
|
|
|
if (allday) {
|
|
allday.checked = false;
|
|
}
|
|
|
|
this._returnTo = null;
|
|
this._markReadonly(false);
|
|
this.event = null;
|
|
this.busytime = null;
|
|
|
|
this.alarmList.innerHTML = '';
|
|
|
|
this.form.reset();
|
|
},
|
|
|
|
onactive: function() {
|
|
EventBase.prototype.onactive.apply(this, arguments);
|
|
this.calendarStream = core.bridge.observeCalendars();
|
|
this.calendarStream.listen(this._renderCalendars.bind(this));
|
|
},
|
|
|
|
oninactive: function() {
|
|
EventBase.prototype.oninactive.apply(this, arguments);
|
|
this.reset();
|
|
this.calendarStream && this.calendarStream.cancel();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* The fields on our event model which urlparams may override.
|
|
* @enum {string}
|
|
*/
|
|
ModifyEvent.OverrideableField = {
|
|
CALENDAR_ID: 'calendarId',
|
|
DESCRIPTION: 'description',
|
|
END_DATE: 'endDate',
|
|
IS_ALL_DAY: 'isAllDay',
|
|
LOCATION: 'location',
|
|
START_DATE: 'startDate',
|
|
TITLE: 'title'
|
|
};
|
|
|
|
});
|