icalendar 0.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +56 -0
- data/GPL +340 -0
- data/README +121 -0
- data/Rakefile +101 -0
- data/docs/api/classes/Array.html +146 -0
- data/docs/api/classes/Date.html +157 -0
- data/docs/api/classes/DateTime.html +178 -0
- data/docs/api/classes/Fixnum.html +146 -0
- data/docs/api/classes/Float.html +146 -0
- data/docs/api/classes/Icalendar/Alarm.html +184 -0
- data/docs/api/classes/Icalendar/Base.html +118 -0
- data/docs/api/classes/Icalendar/Calendar.html +411 -0
- data/docs/api/classes/Icalendar/Component.html +306 -0
- data/docs/api/classes/Icalendar/DateProp.html +187 -0
- data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +195 -0
- data/docs/api/classes/Icalendar/Event.html +202 -0
- data/docs/api/classes/Icalendar/Freebusy.html +157 -0
- data/docs/api/classes/Icalendar/InvalidComponentClass.html +117 -0
- data/docs/api/classes/Icalendar/InvalidPropertyValue.html +117 -0
- data/docs/api/classes/Icalendar/Journal.html +190 -0
- data/docs/api/classes/Icalendar/Parameter.html +166 -0
- data/docs/api/classes/Icalendar/Parser.html +447 -0
- data/docs/api/classes/Icalendar/Timezone.html +197 -0
- data/docs/api/classes/Icalendar/Todo.html +199 -0
- data/docs/api/classes/String.html +160 -0
- data/docs/api/classes/Time.html +161 -0
- data/docs/api/created.rid +1 -0
- data/docs/api/files/COPYING.html +163 -0
- data/docs/api/files/GPL.html +531 -0
- data/docs/api/files/README.html +241 -0
- data/docs/api/files/lib/icalendar/base_rb.html +108 -0
- data/docs/api/files/lib/icalendar/calendar_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/alarm_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/event_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/freebusy_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/journal_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/timezone_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component/todo_rb.html +101 -0
- data/docs/api/files/lib/icalendar/component_rb.html +101 -0
- data/docs/api/files/lib/icalendar/conversions_rb.html +108 -0
- data/docs/api/files/lib/icalendar/helpers_rb.html +101 -0
- data/docs/api/files/lib/icalendar/parameter_rb.html +101 -0
- data/docs/api/files/lib/icalendar/parser_rb.html +109 -0
- data/docs/api/files/lib/icalendar_rb.html +118 -0
- data/docs/api/fr_class_index.html +48 -0
- data/docs/api/fr_file_index.html +43 -0
- data/docs/api/fr_method_index.html +63 -0
- data/docs/api/index.html +24 -0
- data/docs/api/rdoc-style.css +208 -0
- data/docs/examples/create_cal.rb +40 -0
- data/docs/examples/parse_cal.rb +19 -0
- data/docs/examples/single_event.ics +18 -0
- data/docs/rfcs/rfc2425.pdf +0 -0
- data/docs/rfcs/rfc2426.pdf +0 -0
- data/docs/rfcs/rfc2445.pdf +0 -0
- data/docs/rfcs/rfc2446.pdf +0 -0
- data/docs/rfcs/rfc2447.pdf +0 -0
- data/docs/rfcs/rfc3283.txt +738 -0
- data/lib/icalendar.rb +27 -0
- data/lib/icalendar/#helpers.rb# +92 -0
- data/lib/icalendar/base.rb +31 -0
- data/lib/icalendar/calendar.rb +112 -0
- data/lib/icalendar/component.rb +253 -0
- data/lib/icalendar/component/alarm.rb +35 -0
- data/lib/icalendar/component/event.rb +68 -0
- data/lib/icalendar/component/freebusy.rb +35 -0
- data/lib/icalendar/component/journal.rb +61 -0
- data/lib/icalendar/component/timezone.rb +43 -0
- data/lib/icalendar/component/todo.rb +65 -0
- data/lib/icalendar/conversions.rb +115 -0
- data/lib/icalendar/helpers.rb +109 -0
- data/lib/icalendar/parameter.rb +33 -0
- data/lib/icalendar/parser.rb +395 -0
- data/test/calendar_test.rb +46 -0
- data/test/component/event_test.rb +47 -0
- data/test/component_test.rb +74 -0
- data/test/parser_test.rb +83 -0
- data/test/property_helpers.rb +35 -0
- data/test/simplecal.ics +119 -0
- data/test/single_event.ics +23 -0
- metadata +135 -0
data/lib/icalendar.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Jeff Rose
|
3
|
+
|
4
|
+
This library is free software; you can redistribute it and/or modify it
|
5
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
6
|
+
details.
|
7
|
+
=end
|
8
|
+
|
9
|
+
$:.unshift(File.dirname(__FILE__))
|
10
|
+
|
11
|
+
# Base classes and mixin modules
|
12
|
+
require 'icalendar/conversions'
|
13
|
+
#require 'icalendar/helpers'
|
14
|
+
require 'icalendar/base'
|
15
|
+
require 'icalendar/component'
|
16
|
+
|
17
|
+
# Calendar and components
|
18
|
+
require 'icalendar/calendar'
|
19
|
+
require 'icalendar/component/event'
|
20
|
+
require 'icalendar/component/journal'
|
21
|
+
require 'icalendar/component/todo'
|
22
|
+
require 'icalendar/component/freebusy'
|
23
|
+
require 'icalendar/component/timezone'
|
24
|
+
require 'icalendar/component/alarm'
|
25
|
+
|
26
|
+
# Calendar parser
|
27
|
+
require 'icalendar/parser'
|
@@ -0,0 +1,92 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Jeff Rose
|
3
|
+
Copyright (C) 2005 Sam Roberts
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or modify it
|
6
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
7
|
+
details.
|
8
|
+
=end
|
9
|
+
|
10
|
+
module Icalendar
|
11
|
+
module DateProp
|
12
|
+
# You have to do this to mixin class methods rather than instance methods.
|
13
|
+
def self.append_features(base)
|
14
|
+
super
|
15
|
+
klass.extend(ClassMethods)
|
16
|
+
end
|
17
|
+
|
18
|
+
# This is made a sub-module just so it can be added as class
|
19
|
+
# methods rather than instance methods.
|
20
|
+
module ClassMethods
|
21
|
+
def ical_property(dp, alias_name = nil)
|
22
|
+
dp = "#{dp}".strip.downcase
|
23
|
+
getter = dp
|
24
|
+
setter = "#{dp}="
|
25
|
+
query = "#{dp}?"
|
26
|
+
|
27
|
+
unless instance_methods.include? getter
|
28
|
+
code = <<-code
|
29
|
+
def #{getter}(*a)
|
30
|
+
if a.empty?
|
31
|
+
@properties[#{dp.upcase}]
|
32
|
+
else
|
33
|
+
self.#{dp} = a.first
|
34
|
+
end
|
35
|
+
end
|
36
|
+
code
|
37
|
+
|
38
|
+
module_eval code
|
39
|
+
end
|
40
|
+
|
41
|
+
unless instance_methods.include? setter
|
42
|
+
code = <<-code
|
43
|
+
def #{setter} a
|
44
|
+
@properties[#{dp.upcase}] = a
|
45
|
+
end
|
46
|
+
code
|
47
|
+
|
48
|
+
module_eval code
|
49
|
+
end
|
50
|
+
|
51
|
+
unless instance_methods.include? query
|
52
|
+
code = <<-code
|
53
|
+
def #{query}
|
54
|
+
@properties.has_key?(#{dp.upcase})
|
55
|
+
end
|
56
|
+
code
|
57
|
+
|
58
|
+
module_eval code
|
59
|
+
end
|
60
|
+
|
61
|
+
# Define the getter
|
62
|
+
getter = "get#{property.to_s.capitalize}"
|
63
|
+
define_method(getter.to_sym) do
|
64
|
+
puts "inside getting..."
|
65
|
+
getDateProperty(property.to_s.upcase)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Define the setter
|
69
|
+
setter = "set#{property.to_s.capitalize}"
|
70
|
+
define_method(setter.to_sym) do |*params|
|
71
|
+
date = params[0]
|
72
|
+
utc = params[1]
|
73
|
+
puts "inside setting..."
|
74
|
+
setDateProperty(property.to_s.upcase, date, utc)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Create aliases if a name was specified
|
78
|
+
# if not aliasName.nil?
|
79
|
+
# gasym = "get#{aliasName.to_s.capitalize}".to_sym
|
80
|
+
# gsym = getter.to_sym
|
81
|
+
# alias gasym gsym
|
82
|
+
|
83
|
+
# sasym = "set#{aliasName.to_s.capitalize}".to_sym
|
84
|
+
# ssym = setter.to_sym
|
85
|
+
# alias sasym ssym
|
86
|
+
# end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Jeff Rose
|
3
|
+
|
4
|
+
This library is free software; you can redistribute it and/or modify it
|
5
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
6
|
+
details.
|
7
|
+
=end
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
module Icalendar #:nodoc:
|
11
|
+
|
12
|
+
# A simple error class to differentiate iCalendar library exceptions
|
13
|
+
# from ruby language exceptions or others.
|
14
|
+
class IcalendarError < StandardError #:nodoc:
|
15
|
+
end
|
16
|
+
|
17
|
+
# Exception used when the library encounters a bogus calendar component.
|
18
|
+
class InvalidComponentClass < IcalendarError
|
19
|
+
end
|
20
|
+
|
21
|
+
# Exception used when the library encounters a bogus property value.
|
22
|
+
class InvalidPropertyValue < IcalendarError
|
23
|
+
end
|
24
|
+
|
25
|
+
# This class serves as the base class for just about everything in
|
26
|
+
# the library so that the logging system can be configured in one place.
|
27
|
+
class Base
|
28
|
+
@@logger = Logger.new(STDERR)
|
29
|
+
@@logger.level = Logger::WARN
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Jeff Rose
|
3
|
+
|
4
|
+
This library is free software; you can redistribute it and/or modify it
|
5
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
6
|
+
details.
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Icalendar
|
10
|
+
|
11
|
+
|
12
|
+
class Calendar < Component
|
13
|
+
attr_accessor :events, :todos, :journals, :freebusys, :timezones
|
14
|
+
|
15
|
+
ical_property :calscale, :calendar_scale
|
16
|
+
ical_property :prodid, :product_id
|
17
|
+
ical_property :version
|
18
|
+
ical_property :method
|
19
|
+
|
20
|
+
def initialize()
|
21
|
+
super("VCALENDAR")
|
22
|
+
@properties = {}
|
23
|
+
@property_params = {}
|
24
|
+
|
25
|
+
@events = []
|
26
|
+
@todos = []
|
27
|
+
@journals = []
|
28
|
+
@freebusys = []
|
29
|
+
@timezones = []
|
30
|
+
|
31
|
+
# Set some defaults
|
32
|
+
self.calscale = "GREGORIAN" # Who knows, but this is the only one in the spec.
|
33
|
+
self.prodid = "iCalendar-Ruby" # Current product... Should be overwritten
|
34
|
+
self.version = "2.0" # Version of the specification
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def event(&block)
|
39
|
+
e = Event.new
|
40
|
+
self.add e
|
41
|
+
|
42
|
+
e.instance_eval &block if block
|
43
|
+
|
44
|
+
e
|
45
|
+
end
|
46
|
+
|
47
|
+
def todo(&block)
|
48
|
+
e = Todo.new
|
49
|
+
self.add e
|
50
|
+
|
51
|
+
e.instance_eval &block if block
|
52
|
+
|
53
|
+
e
|
54
|
+
end
|
55
|
+
|
56
|
+
def journal(&block)
|
57
|
+
e = Journal.new
|
58
|
+
self.add e
|
59
|
+
|
60
|
+
e.instance_eval &block if block
|
61
|
+
|
62
|
+
e
|
63
|
+
end
|
64
|
+
|
65
|
+
def freebusy(&block)
|
66
|
+
e = Freebusy.new
|
67
|
+
self.add e
|
68
|
+
|
69
|
+
e.instance_eval &block if block
|
70
|
+
|
71
|
+
e
|
72
|
+
end
|
73
|
+
|
74
|
+
def timezone(&block)
|
75
|
+
e = Timezone.new
|
76
|
+
self.add e
|
77
|
+
|
78
|
+
e.instance_eval &block if block
|
79
|
+
|
80
|
+
e
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
#TODO: Implement the rest of these ^ methods for todo etc...
|
85
|
+
|
86
|
+
def add(component)
|
87
|
+
if component.is_a? Event
|
88
|
+
@events << component
|
89
|
+
elsif component.is_a? Todo
|
90
|
+
@todos << component
|
91
|
+
elsif component.is_a? Journal
|
92
|
+
@journals << component
|
93
|
+
elsif component.is_a? Freebusy
|
94
|
+
@freebusys << component
|
95
|
+
elsif component.is_a? Timezone
|
96
|
+
@timezones << component
|
97
|
+
else
|
98
|
+
raise InvalidComponentClass
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_ical
|
103
|
+
print_string do |s|
|
104
|
+
@events.each { |event| s << event.to_ical }
|
105
|
+
@todos.each { |todo| s << todo.to_ical }
|
106
|
+
@journals.each { |journal| s << journal.to_ical }
|
107
|
+
@freebusys.each { |freebusy| s << freebusy.to_ical }
|
108
|
+
@timezones.each { |timezone| s << timezone.to_ical }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Jeff Rose
|
3
|
+
|
4
|
+
This library is free software; you can redistribute it and/or modify it
|
5
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
6
|
+
details.
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Icalendar
|
10
|
+
# The body of the iCalendar object consists of a sequence of calendar
|
11
|
+
# properties and one or more calendar components. The calendar
|
12
|
+
# properties are attributes that apply to the calendar as a whole. The
|
13
|
+
# calendar components are collections of properties that express a
|
14
|
+
# particular calendar semantic. For example, the calendar component can
|
15
|
+
# specify an Event, a Todo, a Journal entry, Timezone information, or
|
16
|
+
# Freebusy time information, or an Alarm.
|
17
|
+
class Component < Icalendar::Base
|
18
|
+
attr_reader :name
|
19
|
+
attr_accessor :properties, :property_params
|
20
|
+
|
21
|
+
@@multi_properties = {}
|
22
|
+
|
23
|
+
def initialize(name)
|
24
|
+
@name = name
|
25
|
+
@properties = {}
|
26
|
+
@property_params = {}
|
27
|
+
|
28
|
+
@@logger.info("New #{@name[1,@name.size].capitalize}...")
|
29
|
+
end
|
30
|
+
|
31
|
+
def print_string
|
32
|
+
s = ""
|
33
|
+
|
34
|
+
# Begin a new component
|
35
|
+
s << "BEGIN:#{@name.upcase}\r\n"
|
36
|
+
|
37
|
+
# Then print the properties, possible parameters and potentially
|
38
|
+
# multiple parameter values for each parameter.
|
39
|
+
@properties.each do |key,value|
|
40
|
+
# Property name
|
41
|
+
s << "#{key.upcase}"
|
42
|
+
|
43
|
+
# Possible parameters
|
44
|
+
if @property_params.has_key?(key)
|
45
|
+
params = @property_params[key]
|
46
|
+
params.each do |key,val|
|
47
|
+
s << ";#{key}"
|
48
|
+
val = [ val ] unless val.respond_to?(:to_ary)
|
49
|
+
|
50
|
+
# Possible parameter values
|
51
|
+
unless val.empty?
|
52
|
+
s << "="
|
53
|
+
sep = "" # First entry comes after = sign, but then we need commas
|
54
|
+
val.each do |pval|
|
55
|
+
if pval.respond_to? :to_ical
|
56
|
+
s << sep << pval.to_ical
|
57
|
+
sep = ","
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Property value
|
65
|
+
s << ":#{value.to_ical}\r\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
# Any custom body of the derived component
|
69
|
+
yield(s)
|
70
|
+
|
71
|
+
# End of this component
|
72
|
+
s << "END:#{@name.upcase}\r\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
# TODO: Look into the x-property, x-param stuff...
|
76
|
+
def custom_property(name, value)
|
77
|
+
@properties[name] = value
|
78
|
+
end
|
79
|
+
|
80
|
+
def multi_property?(name)
|
81
|
+
@@multi_properties.has_key?(name)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Make it protected so we can monitor usage...
|
85
|
+
protected
|
86
|
+
|
87
|
+
# Define a set of methods supporting a new property
|
88
|
+
def Component.ical_property(property, alias_name = nil, prop_name = nil)
|
89
|
+
property = "#{property}".strip.downcase
|
90
|
+
getter = "#{property}"
|
91
|
+
setter = "#{property}="
|
92
|
+
query = "#{property}?"
|
93
|
+
alias_name = "#{alias_name}".strip.downcase unless alias_name.nil?
|
94
|
+
|
95
|
+
# If a prop_name was given then we use that for the actual storage
|
96
|
+
property = "#{prop_name}".strip.upcase unless prop_name.nil?
|
97
|
+
|
98
|
+
# Change underscores in property name to a dash
|
99
|
+
property[/_/] = '-' if property =~ /_/
|
100
|
+
|
101
|
+
# All properties names are stored in caps...
|
102
|
+
property = property.upcase
|
103
|
+
|
104
|
+
unless instance_methods.include? getter
|
105
|
+
code = <<-code
|
106
|
+
def #{getter}(*a)
|
107
|
+
if a.empty?
|
108
|
+
@properties["#{property}"]
|
109
|
+
else
|
110
|
+
self.#{getter} = a.first
|
111
|
+
end
|
112
|
+
end
|
113
|
+
code
|
114
|
+
|
115
|
+
class_eval code, "component.rb", 124
|
116
|
+
|
117
|
+
alias_method("#{alias_name}", "#{getter}") unless alias_name.nil?
|
118
|
+
end
|
119
|
+
|
120
|
+
unless instance_methods.include? setter
|
121
|
+
code = <<-code
|
122
|
+
def #{setter} a
|
123
|
+
unless a.respond_to?(:to_ical)
|
124
|
+
raise(NotImplementedError, "Property value does not support to_ical method!")
|
125
|
+
end
|
126
|
+
|
127
|
+
@properties["#{property}"] = a
|
128
|
+
end
|
129
|
+
code
|
130
|
+
|
131
|
+
class_eval code, "component.rb", 134
|
132
|
+
|
133
|
+
alias_method("#{alias_name}=", "#{setter}") unless alias_name.nil?
|
134
|
+
end
|
135
|
+
|
136
|
+
unless instance_methods.include? query
|
137
|
+
code = <<-code
|
138
|
+
def #{query}
|
139
|
+
@properties.has_key?("#{property}")
|
140
|
+
end
|
141
|
+
code
|
142
|
+
|
143
|
+
class_eval code, "component.rb", 144
|
144
|
+
|
145
|
+
alias_method("#{alias_name}\?", "#{query}") unless alias_name.nil?
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Define a set of methods defining a new property, which
|
150
|
+
# supports multiple values for the same property name.
|
151
|
+
def Component.ical_multi_property(property, singular, plural)
|
152
|
+
property = "#{property}".strip.upcase
|
153
|
+
singular = "#{singular}".strip.downcase
|
154
|
+
plural = "#{plural}".strip.downcase
|
155
|
+
|
156
|
+
getter = "#{plural}"
|
157
|
+
setter = "#{plural}="
|
158
|
+
adder = "add_#{singular}"
|
159
|
+
remover = "remove_#{singular}"
|
160
|
+
query = "#{plural}?"
|
161
|
+
|
162
|
+
# Set this key so the parser knows to use an array for
|
163
|
+
# storing this property type.
|
164
|
+
@@multi_properties["#{property}"] = true
|
165
|
+
|
166
|
+
# Getter for whole array
|
167
|
+
unless instance_methods.include? getter
|
168
|
+
code = <<-code
|
169
|
+
def #{getter}(*a)
|
170
|
+
if a.empty?
|
171
|
+
if @properties.has_key?("#{property}")
|
172
|
+
@properties["#{property}"]
|
173
|
+
else
|
174
|
+
[]
|
175
|
+
end
|
176
|
+
else
|
177
|
+
self.#{setter}(a.first)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
code
|
181
|
+
|
182
|
+
class_eval code, "component.rb", 186
|
183
|
+
end
|
184
|
+
|
185
|
+
# Setter for whole array
|
186
|
+
unless instance_methods.include? setter
|
187
|
+
code = <<-code
|
188
|
+
def #{setter}(a)
|
189
|
+
if a.respond_to?(:to_ary)
|
190
|
+
a.to_ary.each do |val|
|
191
|
+
unless val.respond_to?(:to_ical)
|
192
|
+
raise(NotImplementedError, "Property values do not support to_ical method!")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
@properties["#{property}"] = a.to_ary
|
197
|
+
|
198
|
+
|
199
|
+
else
|
200
|
+
raise ArgumentError, "#{getter} is a multi-property that must be an array! Use the #{adder} method to add single entries."
|
201
|
+
end
|
202
|
+
end
|
203
|
+
code
|
204
|
+
|
205
|
+
class_eval code, "component.rb", 198
|
206
|
+
end
|
207
|
+
|
208
|
+
# Query for any of these properties
|
209
|
+
unless instance_methods.include? query
|
210
|
+
code = <<-code
|
211
|
+
def #{query}
|
212
|
+
@properties.has_key?("#{property}")
|
213
|
+
end
|
214
|
+
code
|
215
|
+
|
216
|
+
class_eval code, "component.rb", 210
|
217
|
+
end
|
218
|
+
|
219
|
+
# Add another item to this properties array
|
220
|
+
unless instance_methods.include? adder
|
221
|
+
code = <<-code
|
222
|
+
def #{adder}(a)
|
223
|
+
unless a.respond_to?(:to_ical)
|
224
|
+
raise(NotImplementedError, "Property value object does not support to_ical method!")
|
225
|
+
end
|
226
|
+
|
227
|
+
if @properties.has_key?("#{property}")
|
228
|
+
@properties["#{property}"] << a
|
229
|
+
else
|
230
|
+
@properties["#{property}"] = [a]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
code
|
234
|
+
|
235
|
+
class_eval code, "component.rb", 228
|
236
|
+
end
|
237
|
+
|
238
|
+
# Remove an item from this properties array
|
239
|
+
unless instance_methods.include? remover
|
240
|
+
code = <<-code
|
241
|
+
def #{remover}(a)
|
242
|
+
if @properties.has_key?("#{property}")
|
243
|
+
@properties["#{property}"].delete(a)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
code
|
247
|
+
|
248
|
+
class_eval code, "component.rb", 241
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|