UNPKG

ical.js-one.com

Version:

[![Build Status](https://secure.travis-ci.org/mozilla-comm/ical.js.png?branch=master)](http://travis-ci.org/mozilla-comm/ical.js)

299 lines (257 loc) 6.99 kB
ICAL.Property = (function() { 'use strict'; var NAME_INDEX = 0; var PROP_INDEX = 1; var TYPE_INDEX = 2; var VALUE_INDEX = 3; var design = ICAL.design; /** * Provides a nicer interface to any kind of property. * Its important to note that mutations done in the wrapper * directly effect (mutate) the jCal object used to initialize. * * Can also be used to create new properties by passing * the name of the property (as a String). * * * @param {Array|String} jCal raw jCal representation OR * the new name of the property (when creating). * * @param {ICAL.Component} [parent] parent component. */ function Property(jCal, parent) { if (typeof(jCal) === 'string') { // because we a creating by name we need // to find the type when creating the property. var name = jCal; if (name in design.property) { var prop = design.property[name]; if ('defaultType' in prop) { var type = prop.defaultType; } else { var type = design.defaultType; } } else { var type = design.defaultType; } jCal = [name, {}, type]; } this.jCal = jCal; this.parent = parent || null; this._updateType(); } Property.prototype = { get type() { return this.jCal[TYPE_INDEX]; }, get name() { return this.jCal[NAME_INDEX]; }, _updateType: function() { if (this.type in design.value) { var designType = design.value[this.type]; if ('decorate' in design.value[this.type]) { this.isDecorated = true; } else { this.isDecorated = false; } if (this.name in design.property) { if ('multiValue' in design.property[this.name]) { this.isMultiValue = true; } else { this.isMultiValue = false; } } } }, /** * Hydrate a single value. */ _hydrateValue: function(index) { if (this._values && this._values[index]) { return this._values[index]; } // for the case where there is no value. if (this.jCal.length <= (VALUE_INDEX + index)) { return null; } if (this.isDecorated) { if (!this._values) { this._values = []; } return this._values[index] = this._decorate( this.jCal[VALUE_INDEX + index] ); } else { return this.jCal[VALUE_INDEX + index]; } }, _decorate: function(value) { return design.value[this.type].decorate(value, this); }, _undecorate: function(value) { return design.value[this.type].undecorate(value, this); }, _setDecoratedValue: function(value, index) { if (!this._values) { this._values = []; } if (typeof(value) === 'object' && 'icaltype' in value) { // decorated value this.jCal[VALUE_INDEX + index] = this._undecorate(value); this._values[index] = value; } else { // undecorated value this.jCal[VALUE_INDEX + index] = value; this._values[index] = this._decorate(value); } }, /** * Gets a param on the property. * * @param {String} name prop name (lowercase). * @return {String} prop value. */ getParameter: function(name) { return this.jCal[PROP_INDEX][name]; }, /** * Sets a param on the property. * * @param {String} value property value. */ setParameter: function(name, value) { this.jCal[PROP_INDEX][name] = value; }, /** * Removes a parameter * * @param {String} name prop name (lowercase). */ removeParameter: function(name) { return delete this.jCal[PROP_INDEX][name]; }, /** * Get the default type based on this property's name. * * @return {String} the default type for this property. */ getDefaultType: function() { var name = this.name if (name in design.property) { var details = design.property[name]; if ('defaultType' in details) { return details.defaultType; } } return null; }, /** * Sets type of property and clears out any * existing values of the current type. * * @param {String} type new iCAL type (see design.values). */ resetType: function(type) { this.removeAllValues(); this.jCal[TYPE_INDEX] = type; this._updateType(); }, /** * Finds first property value. * * @return {String} first property value. */ getFirstValue: function() { return this._hydrateValue(0); }, /** * Gets all values on the property. * * NOTE: this creates an array during each call. * * @return {Array} list of values. */ getValues: function() { var len = this.jCal.length - VALUE_INDEX; if (len < 1) { // its possible for a property to have no value. return []; } var i = 0; var result = []; for (; i < len; i++) { result[i] = this._hydrateValue(i); } return result; }, removeAllValues: function() { if (this._values) { this._values.length = 0; } this.jCal.length = 3; }, /** * Sets the values of the property. * Will overwrite the existing values. * * @param {Array} values an array of values. */ setValues: function(values) { if (!this.isMultiValue) { throw new Error( this.name + ': does not not support mulitValue.\n' + 'override isMultiValue' ); } var len = values.length; var i = 0; this.removeAllValues(); if (len > 0 && typeof(values[0]) === 'object' && 'icaltype' in values[0]) { this.resetType(values[0].icaltype); } if (this.isDecorated) { for (; i < len; i++) { this._setDecoratedValue(values[i], i); } } else { for (; i < len; i++) { this.jCal[VALUE_INDEX + i] = values[i]; } } }, /** * Sets the current value of the property. If this is a multi-value * property, all other values will be removed. * * @param {String|Object} value new prop value. */ setValue: function(value) { this.removeAllValues(); if (typeof(value) === 'object' && 'icaltype' in value) { this.resetType(value.icaltype); } if (this.isDecorated) { this._setDecoratedValue(value, 0); } else { this.jCal[VALUE_INDEX] = value; } }, /** * Returns the jCal representation of this property. * * @return {Object} jCal. */ toJSON: function() { return this.jCal; }, toICAL: function() { return ICAL.stringify.property( this.jCal ); } }; return Property; }());