rhodes 2.0.0.beta1 → 2.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/LICENSE +19 -674
- data/Manifest.txt +21 -4
- data/README.textile +5 -36
- data/Rakefile +5 -0
- data/lib/build/jake.rb +3 -1
- data/lib/extensions/rexml/rexml/document.rb +2 -0
- data/lib/extensions/rexml/rexml/parsers/baseparser.rb +0 -6
- data/lib/extensions/rhoxml/rexml/child.rb +96 -0
- data/lib/extensions/rhoxml/rexml/document.rb +527 -0
- data/lib/extensions/rhoxml/rexml/element.rb +987 -0
- data/lib/extensions/rhoxml/rexml/encoding.rb +71 -0
- data/lib/extensions/rhoxml/rexml/encodings/US-ASCII.rb +30 -0
- data/lib/extensions/rhoxml/rexml/encodings/UTF-16.rb +35 -0
- data/lib/extensions/rhoxml/rexml/encodings/UTF-8.rb +18 -0
- data/lib/extensions/rhoxml/rexml/namespace.rb +47 -0
- data/lib/extensions/rhoxml/rexml/node.rb +76 -0
- data/lib/extensions/rhoxml/rexml/parent.rb +166 -0
- data/lib/extensions/rhoxml/rexml/parseexception.rb +51 -0
- data/lib/extensions/rhoxml/rexml/parsers/baseparser.rb +531 -0
- data/lib/extensions/rhoxml/rexml/parsers/treeparser.rb +100 -0
- data/lib/extensions/rhoxml/rexml/parsers/xpathparser.rb +698 -0
- data/lib/extensions/rhoxml/rexml/set.rb +1274 -0
- data/lib/extensions/rhoxml/rexml/source.rb +258 -0
- data/lib/extensions/rhoxml/rexml/xmltokens.rb +18 -0
- data/lib/extensions/rhoxml/rexml/xpath.rb +77 -0
- data/lib/extensions/rhoxml/rexml/xpath_parser.rb +806 -0
- data/lib/framework/builtinME.rb +2 -0
- data/lib/framework/dateME.rb +5 -1
- data/lib/framework/rho/render.rb +10 -2
- data/lib/framework/rhom/rhom_object_factory.rb +2 -1
- data/lib/framework/singleton.rb +1 -1
- data/platform/android/Rhodes/jni/src/rhodes.cpp +2 -4
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +23 -18
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +42 -69
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +59 -7
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +1 -1
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/Annotation.java +1 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/MapView.java +97 -85
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/SmsUriHandler.java +52 -0
- data/platform/android/build/RhodesSRC_build.files +1 -0
- data/platform/android/build/android.rake +38 -14
- data/platform/bb/RubyVM/RubyVM.jdp +1 -0
- data/platform/bb/build/RubyVM_build.files +1 -0
- data/platform/bb/build/bb.rake +44 -2
- data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +1 -1
- data/platform/bb/rhodes/rhodes.jdp +4 -4
- data/platform/bb/rhodes/src/com/rho/BrowserAdapter.java +8 -4
- data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +149 -17
- data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +20 -17
- data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +54 -28
- data/platform/bb/rhodes/src/rhomobile/mapview/Annotation.java +1 -0
- data/platform/bb/rhodes/src/rhomobile/mapview/GoogleMapField.java +37 -11
- data/platform/bb/rhodes/src/rhomobile/mapview/MapView.java +49 -19
- data/platform/bb/rhodes/src/rhomobile/mapview/MapViewScreen.java +6 -0
- data/platform/iphone/Classes/MapView/GoogleGeocoder.h +6 -7
- data/platform/iphone/Classes/MapView/GoogleGeocoder.m +70 -70
- data/platform/iphone/Classes/MapView/MapAnnotation.h +5 -3
- data/platform/iphone/Classes/MapView/MapAnnotation.m +10 -8
- data/platform/iphone/Classes/MapView/MapViewController.h +13 -10
- data/platform/iphone/Classes/MapView/MapViewController.m +131 -72
- data/platform/iphone/Classes/Rhodes.h +2 -0
- data/platform/iphone/Classes/Rhodes.m +13 -1
- data/platform/iphone/Classes/SimpleMainView.m +0 -1
- data/platform/iphone/Classes/TabbedMainView.m +5 -6
- data/platform/shared/common/RhoTime.h +2 -2
- data/platform/shared/common/RhodesApp.cpp +1 -1
- data/platform/shared/db/DBAdapter.cpp +6 -0
- data/platform/shared/net/CURLNetRequest.cpp +23 -1
- data/platform/shared/ruby/thread_win32.c +9 -1
- data/platform/shared/rubyJVM/src/com/rho/Capabilities.java +6 -0
- data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +1 -1
- data/platform/shared/rubyJVM/src/com/rho/sync/ClientRegister.java +1 -1
- data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubySymbol_Methods.java +6 -1
- data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubyTime_Methods.java +3 -3
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/InputStreamExecutor.java +1 -1
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyArray.java +15 -3
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyString.java +10 -2
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyTime.java +12 -1
- data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubyKernelModule.java +18 -9
- data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubySymbol.java +5 -0
- data/platform/shared/rubyJVM/src/org/json/me/JSONArray.java +2 -1
- data/platform/shared/unzip/unzip.cpp +1 -1
- data/platform/wm/build/wm.rake +27 -6
- data/platform/wm/rhodes/Alert.cpp +335 -5
- data/platform/wm/rhodes/Alert.h +84 -1
- data/platform/wm/rhodes/MainWindow.cpp +28 -6
- data/platform/wm/rhodes/MainWindow.h +7 -2
- data/platform/wm/rhodes/Rhodes.cpp +23 -0
- data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +2 -1
- data/platform/wm/rhodes/stdafx.h +1 -0
- data/platform/wm/tools/detool/detool.cpp +405 -14
- data/rakefile.rb +5 -0
- data/res/build-tools/detool.exe +0 -0
- data/res/generators/rhogen.rb +2 -0
- data/rhodes.gemspec +1 -1
- data/spec/framework_spec/app/spec/fixtures/object_values.txt +1 -1
- data/spec/framework_spec/app/spec/pagination/fixtures/object_values.txt +1 -1
- data/spec/framework_spec/app/spec/rhom_object_spec.rb +12 -12
- metadata +23 -6
- data/LICENSING_OPTIONS +0 -1
- data/platform/bb/build/rhodesApp.rapc +0 -9
- data/res/generators/templates/source/source_adapter.rb +0 -48
- data/rhobuild.yml +0 -37
data/Manifest.txt
CHANGED
@@ -164,6 +164,25 @@ lib/extensions/rholang/lang_se.rb
|
|
164
164
|
lib/extensions/rholang/lang_sr.rb
|
165
165
|
lib/extensions/rholang/rhoerror_ru.rb
|
166
166
|
lib/extensions/rholang/rhomsg_ru.rb
|
167
|
+
lib/extensions/rhoxml/rexml/child.rb
|
168
|
+
lib/extensions/rhoxml/rexml/document.rb
|
169
|
+
lib/extensions/rhoxml/rexml/element.rb
|
170
|
+
lib/extensions/rhoxml/rexml/encoding.rb
|
171
|
+
lib/extensions/rhoxml/rexml/encodings/US-ASCII.rb
|
172
|
+
lib/extensions/rhoxml/rexml/encodings/UTF-16.rb
|
173
|
+
lib/extensions/rhoxml/rexml/encodings/UTF-8.rb
|
174
|
+
lib/extensions/rhoxml/rexml/namespace.rb
|
175
|
+
lib/extensions/rhoxml/rexml/node.rb
|
176
|
+
lib/extensions/rhoxml/rexml/parent.rb
|
177
|
+
lib/extensions/rhoxml/rexml/parseexception.rb
|
178
|
+
lib/extensions/rhoxml/rexml/parsers/baseparser.rb
|
179
|
+
lib/extensions/rhoxml/rexml/parsers/treeparser.rb
|
180
|
+
lib/extensions/rhoxml/rexml/parsers/xpathparser.rb
|
181
|
+
lib/extensions/rhoxml/rexml/set.rb
|
182
|
+
lib/extensions/rhoxml/rexml/source.rb
|
183
|
+
lib/extensions/rhoxml/rexml/xmltokens.rb
|
184
|
+
lib/extensions/rhoxml/rexml/xpath.rb
|
185
|
+
lib/extensions/rhoxml/rexml/xpath_parser.rb
|
167
186
|
lib/extensions/set/set.rb
|
168
187
|
lib/extensions/uri/uri/common.rb
|
169
188
|
lib/extensions/uri/uri/ftp.rb
|
@@ -221,7 +240,6 @@ lib/test/framework_test.rb
|
|
221
240
|
lib/test/rho_stubs.rb
|
222
241
|
lib/test/syncdb.sqlite
|
223
242
|
LICENSE
|
224
|
-
LICENSING_OPTIONS
|
225
243
|
Manifest.txt
|
226
244
|
platform/android/build/android.rake
|
227
245
|
platform/android/build/androidcommon.rb
|
@@ -341,6 +359,7 @@ platform/android/Rhodes/src/com/rhomobile/rhodes/ui/AboutDialog.java
|
|
341
359
|
platform/android/Rhodes/src/com/rhomobile/rhodes/ui/LogOptionsDialog.java
|
342
360
|
platform/android/Rhodes/src/com/rhomobile/rhodes/ui/LogViewDialog.java
|
343
361
|
platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java
|
362
|
+
platform/android/Rhodes/src/com/rhomobile/rhodes/uri/SmsUriHandler.java
|
344
363
|
platform/android/Rhodes/src/com/rhomobile/rhodes/uri/TelUriHandler.java
|
345
364
|
platform/android/Rhodes/src/com/rhomobile/rhodes/uri/UriHandler.java
|
346
365
|
platform/android/Rhodes/src/com/rhomobile/rhodes/uri/VideoUriHandler.java
|
@@ -352,7 +371,6 @@ platform/bb/build/MANIFEST.MF
|
|
352
371
|
platform/bb/build/RhoBundleAlx.erb
|
353
372
|
platform/bb/build/rhodes_build.files
|
354
373
|
platform/bb/build/rhodesApp.csl
|
355
|
-
platform/bb/build/rhodesApp.rapc
|
356
374
|
platform/bb/build/rhodesAppAlx.erb
|
357
375
|
platform/bb/build/RubyVM_build.files
|
358
376
|
platform/bb/build/RubyVM_MANIFEST.MF
|
@@ -1412,6 +1430,7 @@ platform/shared/rubyext/RhoRuby.cpp
|
|
1412
1430
|
platform/shared/rubyext/RhoRuby.h
|
1413
1431
|
platform/shared/rubyext/System.cpp
|
1414
1432
|
platform/shared/rubyext/WebView.h
|
1433
|
+
platform/shared/rubyJVM/src/com/rho/Capabilities.java
|
1415
1434
|
platform/shared/rubyJVM/src/com/rho/Convert.java
|
1416
1435
|
platform/shared/rubyJVM/src/com/rho/DateTimeTokenizer.java
|
1417
1436
|
platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java
|
@@ -3522,7 +3541,6 @@ res/generators/templates/model/new.erb
|
|
3522
3541
|
res/generators/templates/model/show.bb.erb
|
3523
3542
|
res/generators/templates/model/show.erb
|
3524
3543
|
res/generators/templates/model/spec.rb
|
3525
|
-
res/generators/templates/source/source_adapter.rb
|
3526
3544
|
res/generators/templates/spec/app/fileutils.rb
|
3527
3545
|
res/generators/templates/spec/app/mspec/expectations/expectations.rb
|
3528
3546
|
res/generators/templates/spec/app/mspec/expectations/should.rb
|
@@ -3641,7 +3659,6 @@ res/generators/templates/spec/app/spec/webview_spec.rb
|
|
3641
3659
|
res/generators/templates/spec/app/spec_runner.rb
|
3642
3660
|
res/generators/templates/spec/app/SpecRunner/controller.rb
|
3643
3661
|
res/generators/templates/spec/app/SpecRunner/index.erb
|
3644
|
-
rhobuild.yml
|
3645
3662
|
rhobuild.yml.example
|
3646
3663
|
rhodes.gemspec
|
3647
3664
|
spec/framework_spec/app/Account/config.rb
|
data/README.textile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
h1. Rhodes
|
2
2
|
|
3
|
-
The "Rhodes framework":http://github.com/rhomobile/rhodes
|
3
|
+
The "Rhodes framework":http://github.com/rhomobile/rhodes is a framework for building locally executing, device-optimized mobile applications for smartphone devices. These applications are optimized for interacting with transactional enterprise application backends (with synced local data via "RhoSync":http://github.com/rhomobile/rhosync). Rhodes is now available for iPhone, Windows Mobile, Research in Motion (Blackberry) and Symbian smartphones.
|
4
4
|
|
5
|
-
Rhodes is available as an open source product under the
|
5
|
+
Rhodes is available as an open source product under the MIT license. For developers interested a commercial license is still "available":http://rhomobile.com/products/rhodes/license/.
|
6
6
|
|
7
7
|
h2. INTRODUCTION
|
8
8
|
|
@@ -20,7 +20,7 @@ Rhodes features an application generator called rhogen that generates a control
|
|
20
20
|
|
21
21
|
rhogen app appname
|
22
22
|
|
23
|
-
This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the RhoSync
|
23
|
+
This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the "RhoSync docs":http://wiki.rhomobile.com/index.php/RhoSync_2.0.
|
24
24
|
|
25
25
|
h3. Generate a Model and Associated Controller and Templates
|
26
26
|
|
@@ -33,43 +33,12 @@ This will generate a controller as the file controller.rb and several views as a
|
|
33
33
|
* edit - to edit the actual object
|
34
34
|
* show - to show the object attributes
|
35
35
|
|
36
|
-
h2. DIRECTORY STRUCTURE
|
37
|
-
|
38
|
-
The Rhodes directory structure is outlined below. In a default Rhodes application, there are several subdirectories inside of an app directory, one for each model or synced data object. For example, there might be subdirectories called Account, Employee, and Case. Each model subdirectory contains a controller in the file controller.rb. These subdirectories each contain a set of template files as Embedded Ruby (ERB) files. These control how data from the model is displayed and what links are available to other actions. Note that this structure is reminiscent of Rails and MERB's structure, but is a bit simpler by design.
|
39
|
-
|
40
|
-
/appname
|
41
|
-
build.yml (contains the settings for running builds)
|
42
|
-
rhoconfig.txt (contains settings for setting the default start and options path)
|
43
|
-
Rakefile
|
44
|
-
/public (contains static resources for the generated objects)
|
45
|
-
/css
|
46
|
-
/images
|
47
|
-
/js
|
48
|
-
/app
|
49
|
-
index.erb
|
50
|
-
layout.erb
|
51
|
-
loading.html
|
52
|
-
/modelname (for example Account)
|
53
|
-
config.rb
|
54
|
-
index.erb
|
55
|
-
new.erb
|
56
|
-
edit.erb
|
57
|
-
show.erb
|
58
|
-
controller.rb
|
59
|
-
/modelname (for example Case)
|
60
|
-
config.rb
|
61
|
-
index.erb
|
62
|
-
new.erb
|
63
|
-
edit.erb
|
64
|
-
show.erb
|
65
|
-
controller.rb
|
66
|
-
|
67
36
|
|
68
37
|
h2. MORE RESOURCES
|
69
38
|
|
70
|
-
There is a "tutorial available":http://rhomobile.com/wiki/index.php
|
39
|
+
There is a "tutorial available":http://rhomobile.com/wiki/index.php/Mobilizing_Your_Application_with_Rhomobile on the "Rhomobile site":http://www.rhomobile.com. This includes thorough and current platform by platform build instructions.
|
71
40
|
|
72
|
-
The "Rhodes spec":http://rhomobile.com/wiki/index.php
|
41
|
+
The "Rhodes spec":http://rhomobile.com/wiki/index.php/Rhodes is also available on the "Rhomobile documentation wiki":http://rhomobile.com/wiki/index.php?title=Rhomobile.
|
73
42
|
|
74
43
|
For further questions "email us":mailto:info@rhomobile.com or join the "Google Group":http://groups.google.com/group/rhomobile.
|
75
44
|
|
data/Rakefile
CHANGED
@@ -275,6 +275,11 @@ def common_bundle_start(startdir, dest)
|
|
275
275
|
end
|
276
276
|
end
|
277
277
|
|
278
|
+
if $excludeextlib
|
279
|
+
chdir dest
|
280
|
+
$excludeextlib.each {|e| Dir.glob(e).each {|f| rm f}}
|
281
|
+
end
|
282
|
+
|
278
283
|
chdir startdir
|
279
284
|
#throw "ME"
|
280
285
|
cp_r app + '/app',File.join($srcdir,'apps')
|
data/lib/build/jake.rb
CHANGED
@@ -241,7 +241,9 @@ class Jake
|
|
241
241
|
|
242
242
|
if cldc and icon
|
243
243
|
f.write "MIDlet-1: " + title + "," + icon + ",\n"
|
244
|
-
|
244
|
+
puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! service_enabled: #{$service_enabled}"
|
245
|
+
$stdout.flush
|
246
|
+
f.write "RIM-MIDlet-Flags-1: 1\n" if $service_enabled
|
245
247
|
end
|
246
248
|
|
247
249
|
f.close
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "rexml/node"
|
2
|
+
|
3
|
+
module REXML
|
4
|
+
##
|
5
|
+
# A Child object is something contained by a parent, and this class
|
6
|
+
# contains methods to support that. Most user code will not use this
|
7
|
+
# class directly.
|
8
|
+
class Child
|
9
|
+
include Node
|
10
|
+
attr_reader :parent # The Parent of this object
|
11
|
+
|
12
|
+
# Constructor. Any inheritors of this class should call super to make
|
13
|
+
# sure this method is called.
|
14
|
+
# parent::
|
15
|
+
# if supplied, the parent of this child will be set to the
|
16
|
+
# supplied value, and self will be added to the parent
|
17
|
+
def initialize( parent = nil )
|
18
|
+
@parent = nil
|
19
|
+
# Declare @parent, but don't define it. The next line sets the
|
20
|
+
# parent.
|
21
|
+
parent.add( self ) if parent
|
22
|
+
end
|
23
|
+
|
24
|
+
# Replaces this object with another object. Basically, calls
|
25
|
+
# Parent.replace_child
|
26
|
+
#
|
27
|
+
# Returns:: self
|
28
|
+
def replace_with( child )
|
29
|
+
@parent.replace_child( self, child )
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# Removes this child from the parent.
|
34
|
+
#
|
35
|
+
# Returns:: self
|
36
|
+
def remove
|
37
|
+
unless @parent.nil?
|
38
|
+
@parent.delete self
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# Sets the parent of this child to the supplied argument.
|
44
|
+
#
|
45
|
+
# other::
|
46
|
+
# Must be a Parent object. If this object is the same object as the
|
47
|
+
# existing parent of this child, no action is taken. Otherwise, this
|
48
|
+
# child is removed from the current parent (if one exists), and is added
|
49
|
+
# to the new parent.
|
50
|
+
# Returns:: The parent added
|
51
|
+
def parent=( other )
|
52
|
+
return @parent if @parent == other
|
53
|
+
@parent.delete self if defined?( @parent ) and @parent
|
54
|
+
@parent = other
|
55
|
+
end
|
56
|
+
|
57
|
+
alias :next_sibling :next_sibling_node
|
58
|
+
alias :previous_sibling :previous_sibling_node
|
59
|
+
|
60
|
+
# Sets the next sibling of this child. This can be used to insert a child
|
61
|
+
# after some other child.
|
62
|
+
# a = Element.new("a")
|
63
|
+
# b = a.add_element("b")
|
64
|
+
# c = Element.new("c")
|
65
|
+
# b.next_sibling = c
|
66
|
+
# # => <a><b/><c/></a>
|
67
|
+
def next_sibling=( other )
|
68
|
+
parent.insert_after self, other
|
69
|
+
end
|
70
|
+
|
71
|
+
# Sets the previous sibling of this child. This can be used to insert a
|
72
|
+
# child before some other child.
|
73
|
+
# a = Element.new("a")
|
74
|
+
# b = a.add_element("b")
|
75
|
+
# c = Element.new("c")
|
76
|
+
# b.previous_sibling = c
|
77
|
+
# # => <a><b/><c/></a>
|
78
|
+
def previous_sibling=(other)
|
79
|
+
parent.insert_before self, other
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns:: the document this child belongs to, or nil if this child
|
83
|
+
# belongs to no document
|
84
|
+
def document
|
85
|
+
return parent.document unless parent.nil?
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
# This doesn't yet handle encodings
|
90
|
+
def bytes
|
91
|
+
encoding = document.encoding
|
92
|
+
|
93
|
+
to_s
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,527 @@
|
|
1
|
+
require "rexml/element"
|
2
|
+
#require "rexml/xmldecl"
|
3
|
+
#require 'rexml/text'
|
4
|
+
require "rexml/source"
|
5
|
+
#require "rexml/doctype"
|
6
|
+
=begin
|
7
|
+
require "rexml/comment"
|
8
|
+
|
9
|
+
require "rexml/instruction"
|
10
|
+
require "rexml/rexml"
|
11
|
+
require "rexml/parseexception"
|
12
|
+
require "rexml/output"
|
13
|
+
=end
|
14
|
+
if !defined? RHO_ME
|
15
|
+
require "rexml/parsers/baseparser"
|
16
|
+
end
|
17
|
+
#require "rexml/parsers/streamparser"
|
18
|
+
|
19
|
+
require "rexml/parsers/treeparser"
|
20
|
+
|
21
|
+
module REXML
|
22
|
+
class Comment < Child
|
23
|
+
include Comparable
|
24
|
+
START = "<!--"
|
25
|
+
STOP = "-->"
|
26
|
+
|
27
|
+
# The content text
|
28
|
+
|
29
|
+
attr_accessor :string
|
30
|
+
|
31
|
+
##
|
32
|
+
# Constructor. The first argument can be one of three types:
|
33
|
+
# @param first If String, the contents of this comment are set to the
|
34
|
+
# argument. If Comment, the argument is duplicated. If
|
35
|
+
# Source, the argument is scanned for a comment.
|
36
|
+
# @param second If the first argument is a Source, this argument
|
37
|
+
# should be nil, not supplied, or a Parent to be set as the parent
|
38
|
+
# of this object
|
39
|
+
def initialize( first, second = nil )
|
40
|
+
#puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
|
41
|
+
super(second)
|
42
|
+
if first.kind_of? String
|
43
|
+
@string = first
|
44
|
+
elsif first.kind_of? Comment
|
45
|
+
@string = first.string
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def clone
|
50
|
+
Comment.new self
|
51
|
+
end
|
52
|
+
|
53
|
+
alias :to_s :string
|
54
|
+
|
55
|
+
##
|
56
|
+
# Compares this Comment to another; the contents of the comment are used
|
57
|
+
# in the comparison.
|
58
|
+
def <=>(other)
|
59
|
+
other.to_s <=> @string
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Compares this Comment to another; the contents of the comment are used
|
64
|
+
# in the comparison.
|
65
|
+
def ==( other )
|
66
|
+
other.kind_of?( Comment ) and
|
67
|
+
(other <=> self) == 0
|
68
|
+
end
|
69
|
+
|
70
|
+
def node_type
|
71
|
+
:comment
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
|
76
|
+
# ... >. DOCTYPES can be used to declare the DTD of a document, as well as
|
77
|
+
# being used to declare entities used in the document.
|
78
|
+
class DocType < Parent
|
79
|
+
include XMLTokens
|
80
|
+
end
|
81
|
+
|
82
|
+
class XMLDecl < Child
|
83
|
+
include Encoding
|
84
|
+
|
85
|
+
DEFAULT_VERSION = "1.0";
|
86
|
+
DEFAULT_ENCODING = "UTF-8";
|
87
|
+
DEFAULT_STANDALONE = "no";
|
88
|
+
START = '<\?xml';
|
89
|
+
STOP = '\?>';
|
90
|
+
|
91
|
+
attr_accessor :version, :standalone
|
92
|
+
attr_reader :writeencoding, :writethis
|
93
|
+
|
94
|
+
def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
|
95
|
+
@writethis = true
|
96
|
+
@writeencoding = !encoding.nil?
|
97
|
+
if version.kind_of? XMLDecl
|
98
|
+
super()
|
99
|
+
@version = version.version
|
100
|
+
self.encoding = version.encoding
|
101
|
+
@writeencoding = version.writeencoding
|
102
|
+
@standalone = version.standalone
|
103
|
+
else
|
104
|
+
super()
|
105
|
+
@version = version
|
106
|
+
self.encoding = encoding
|
107
|
+
@standalone = standalone
|
108
|
+
end
|
109
|
+
@version = DEFAULT_VERSION if @version.nil?
|
110
|
+
end
|
111
|
+
|
112
|
+
def clone
|
113
|
+
XMLDecl.new(self)
|
114
|
+
end
|
115
|
+
|
116
|
+
# indent::
|
117
|
+
# Ignored. There must be no whitespace before an XML declaration
|
118
|
+
# transitive::
|
119
|
+
# Ignored
|
120
|
+
# ie_hack::
|
121
|
+
# Ignored
|
122
|
+
def write(writer, indent=-1, transitive=false, ie_hack=false)
|
123
|
+
return nil unless @writethis or writer.kind_of? Output
|
124
|
+
writer << START.sub(/\\/u, '')
|
125
|
+
if writer.kind_of? Output
|
126
|
+
writer << " #{content writer.encoding}"
|
127
|
+
else
|
128
|
+
writer << " #{content encoding}"
|
129
|
+
end
|
130
|
+
writer << STOP.sub(/\\/u, '')
|
131
|
+
end
|
132
|
+
|
133
|
+
def ==( other )
|
134
|
+
other.kind_of?(XMLDecl) and
|
135
|
+
other.version == @version and
|
136
|
+
other.encoding == self.encoding and
|
137
|
+
other.standalone == @standalone
|
138
|
+
end
|
139
|
+
|
140
|
+
def xmldecl version, encoding, standalone
|
141
|
+
@version = version
|
142
|
+
self.encoding = encoding
|
143
|
+
@standalone = standalone
|
144
|
+
end
|
145
|
+
|
146
|
+
def node_type
|
147
|
+
:xmldecl
|
148
|
+
end
|
149
|
+
|
150
|
+
alias :stand_alone? :standalone
|
151
|
+
alias :old_enc= :encoding=
|
152
|
+
|
153
|
+
def encoding=( enc )
|
154
|
+
if enc.nil?
|
155
|
+
@@old_enc = "UTF-8"
|
156
|
+
@writeencoding = false
|
157
|
+
else
|
158
|
+
@@old_enc = enc
|
159
|
+
@writeencoding = true
|
160
|
+
end
|
161
|
+
self.dowrite
|
162
|
+
end
|
163
|
+
|
164
|
+
# Only use this if you do not want the XML declaration to be written;
|
165
|
+
# this object is ignored by the XML writer. Otherwise, instantiate your
|
166
|
+
# own XMLDecl and add it to the document.
|
167
|
+
#
|
168
|
+
# Note that XML 1.1 documents *must* include an XML declaration
|
169
|
+
def XMLDecl.default
|
170
|
+
rv = XMLDecl.new( "1.0" )
|
171
|
+
rv.nowrite
|
172
|
+
rv
|
173
|
+
end
|
174
|
+
|
175
|
+
def nowrite
|
176
|
+
@writethis = false
|
177
|
+
end
|
178
|
+
|
179
|
+
def dowrite
|
180
|
+
@writethis = true
|
181
|
+
end
|
182
|
+
|
183
|
+
def inspect
|
184
|
+
START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
def content(enc)
|
189
|
+
rv = "version='#@version'"
|
190
|
+
rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i
|
191
|
+
rv << " standalone='#@standalone'" if @standalone
|
192
|
+
rv
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Represents a full XML document, including PIs, a doctype, etc. A
|
197
|
+
# Document has a single child that can be accessed by root().
|
198
|
+
# Note that if you want to have an XML declaration written for a document
|
199
|
+
# you create, you must add one; REXML documents do not write a default
|
200
|
+
# declaration for you. See |DECLARATION| and |write|.
|
201
|
+
class Document < Element
|
202
|
+
# A convenient default XML declaration. If you want an XML declaration,
|
203
|
+
# the easiest way to add one is mydoc << Document::DECLARATION
|
204
|
+
# +DEPRECATED+
|
205
|
+
# Use: mydoc << XMLDecl.default
|
206
|
+
DECLARATION = XMLDecl.default
|
207
|
+
|
208
|
+
# Constructor
|
209
|
+
# @param source if supplied, must be a Document, String, or IO.
|
210
|
+
# Documents have their context and Element attributes cloned.
|
211
|
+
# Strings are expected to be valid XML documents. IOs are expected
|
212
|
+
# to be sources of valid XML documents.
|
213
|
+
# @param context if supplied, contains the context of the document;
|
214
|
+
# this should be a Hash.
|
215
|
+
def initialize( source = nil, context = {} )
|
216
|
+
@entity_expansion_count = 0
|
217
|
+
super()
|
218
|
+
@context = context
|
219
|
+
return if source.nil?
|
220
|
+
if source.kind_of? Document
|
221
|
+
@context = source.context
|
222
|
+
super source
|
223
|
+
else
|
224
|
+
build( source )
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def node_type
|
229
|
+
:document
|
230
|
+
end
|
231
|
+
|
232
|
+
# Should be obvious
|
233
|
+
def clone
|
234
|
+
Document.new self
|
235
|
+
end
|
236
|
+
|
237
|
+
# According to the XML spec, a root node has no expanded name
|
238
|
+
def expanded_name
|
239
|
+
''
|
240
|
+
#d = doc_type
|
241
|
+
#d ? d.name : "UNDEFINED"
|
242
|
+
end
|
243
|
+
|
244
|
+
alias :name :expanded_name
|
245
|
+
|
246
|
+
# We override this, because XMLDecls and DocTypes must go at the start
|
247
|
+
# of the document
|
248
|
+
def add( child )
|
249
|
+
#puts "document.add: #{child}"
|
250
|
+
if child.kind_of? XMLDecl
|
251
|
+
@children.unshift child
|
252
|
+
child.parent = self
|
253
|
+
elsif child.kind_of? DocType
|
254
|
+
# Find first Element or DocType node and insert the decl right
|
255
|
+
# before it. If there is no such node, just insert the child at the
|
256
|
+
# end. If there is a child and it is an DocType, then replace it.
|
257
|
+
insert_before_index = 0
|
258
|
+
@children.find { |x|
|
259
|
+
insert_before_index += 1
|
260
|
+
x.kind_of?(Element) || x.kind_of?(DocType)
|
261
|
+
}
|
262
|
+
if @children[ insert_before_index ] # Not null = not end of list
|
263
|
+
if @children[ insert_before_index ].kind_of DocType
|
264
|
+
@children[ insert_before_index ] = child
|
265
|
+
else
|
266
|
+
@children[ index_before_index-1, 0 ] = child
|
267
|
+
end
|
268
|
+
else # Insert at end of list
|
269
|
+
@children[insert_before_index] = child
|
270
|
+
end
|
271
|
+
child.parent = self
|
272
|
+
else
|
273
|
+
rv = super
|
274
|
+
raise "attempted adding second root element to document" if @elements.size > 1
|
275
|
+
rv
|
276
|
+
end
|
277
|
+
end
|
278
|
+
alias :<< :add
|
279
|
+
|
280
|
+
def add_element(arg=nil, arg2=nil)
|
281
|
+
#puts "document.add_element: #{arg}; #{arg2}"
|
282
|
+
rv = super
|
283
|
+
raise "attempted adding second root element to document" if @elements.size > 1
|
284
|
+
rv
|
285
|
+
end
|
286
|
+
|
287
|
+
# @return the root Element of the document, or nil if this document
|
288
|
+
# has no children.
|
289
|
+
def root
|
290
|
+
elements[1]
|
291
|
+
#self
|
292
|
+
#@children.find { |item| item.kind_of? Element }
|
293
|
+
end
|
294
|
+
|
295
|
+
# @return the DocType child of the document, if one exists,
|
296
|
+
# and nil otherwise.
|
297
|
+
def doctype
|
298
|
+
@children.find { |item| item.kind_of? DocType }
|
299
|
+
end
|
300
|
+
|
301
|
+
# @return the XMLDecl of this document; if no XMLDecl has been
|
302
|
+
# set, the default declaration is returned.
|
303
|
+
def xml_decl
|
304
|
+
rv = @children[0]
|
305
|
+
return rv if rv.kind_of? XMLDecl
|
306
|
+
rv = @children.unshift(XMLDecl.default)[0]
|
307
|
+
end
|
308
|
+
|
309
|
+
# @return the XMLDecl version of this document as a String.
|
310
|
+
# If no XMLDecl has been set, returns the default version.
|
311
|
+
def version
|
312
|
+
xml_decl().version
|
313
|
+
end
|
314
|
+
|
315
|
+
# @return the XMLDecl encoding of this document as a String.
|
316
|
+
# If no XMLDecl has been set, returns the default encoding.
|
317
|
+
def encoding
|
318
|
+
xml_decl().encoding
|
319
|
+
end
|
320
|
+
|
321
|
+
# @return the XMLDecl standalone value of this document as a String.
|
322
|
+
# If no XMLDecl has been set, returns the default setting.
|
323
|
+
def stand_alone?
|
324
|
+
xml_decl().stand_alone?
|
325
|
+
end
|
326
|
+
|
327
|
+
# Write the XML tree out, optionally with indent. This writes out the
|
328
|
+
# entire XML document, including XML declarations, doctype declarations,
|
329
|
+
# and processing instructions (if any are given).
|
330
|
+
#
|
331
|
+
# A controversial point is whether Document should always write the XML
|
332
|
+
# declaration (<?xml version='1.0'?>) whether or not one is given by the
|
333
|
+
# user (or source document). REXML does not write one if one was not
|
334
|
+
# specified, because it adds unnecessary bandwidth to applications such
|
335
|
+
# as XML-RPC.
|
336
|
+
#
|
337
|
+
# See also the classes in the rexml/formatters package for the proper way
|
338
|
+
# to change the default formatting of XML output
|
339
|
+
#
|
340
|
+
# _Examples_
|
341
|
+
# Document.new("<a><b/></a>").serialize
|
342
|
+
#
|
343
|
+
# output_string = ""
|
344
|
+
# tr = Transitive.new( output_string )
|
345
|
+
# Document.new("<a><b/></a>").serialize( tr )
|
346
|
+
#
|
347
|
+
# output::
|
348
|
+
# output an object which supports '<< string'; this is where the
|
349
|
+
# document will be written.
|
350
|
+
# indent::
|
351
|
+
# An integer. If -1, no indenting will be used; otherwise, the
|
352
|
+
# indentation will be twice this number of spaces, and children will be
|
353
|
+
# indented an additional amount. For a value of 3, every item will be
|
354
|
+
# indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
|
355
|
+
# transitive::
|
356
|
+
# If transitive is true and indent is >= 0, then the output will be
|
357
|
+
# pretty-printed in such a way that the added whitespace does not affect
|
358
|
+
# the absolute *value* of the document -- that is, it leaves the value
|
359
|
+
# and number of Text nodes in the document unchanged.
|
360
|
+
# ie_hack::
|
361
|
+
# Internet Explorer is the worst piece of crap to have ever been
|
362
|
+
# written, with the possible exception of Windows itself. Since IE is
|
363
|
+
# unable to parse proper XML, we have to provide a hack to generate XML
|
364
|
+
# that IE's limited abilities can handle. This hack inserts a space
|
365
|
+
# before the /> on empty tags. Defaults to false
|
366
|
+
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
|
367
|
+
if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
|
368
|
+
output = Output.new( output, xml_decl.encoding )
|
369
|
+
end
|
370
|
+
formatter = if indent > -1
|
371
|
+
if transitive
|
372
|
+
require "rexml/formatters/transitive"
|
373
|
+
REXML::Formatters::Transitive.new( indent, ie_hack )
|
374
|
+
else
|
375
|
+
REXML::Formatters::Pretty.new( indent, ie_hack )
|
376
|
+
end
|
377
|
+
else
|
378
|
+
REXML::Formatters::Default.new( ie_hack )
|
379
|
+
end
|
380
|
+
formatter.write( self, output )
|
381
|
+
end
|
382
|
+
|
383
|
+
|
384
|
+
def Document::parse_stream( source, listener )
|
385
|
+
Parsers::StreamParser.new( source, listener ).parse
|
386
|
+
end
|
387
|
+
|
388
|
+
@@entity_expansion_limit = 10_000
|
389
|
+
|
390
|
+
# Set the entity expansion limit. By default the limit is set to 10000.
|
391
|
+
def Document::entity_expansion_limit=( val )
|
392
|
+
@@entity_expansion_limit = val
|
393
|
+
end
|
394
|
+
|
395
|
+
# Get the entity expansion limit. By default the limit is set to 10000.
|
396
|
+
def Document::entity_expansion_limit
|
397
|
+
return @@entity_expansion_limit
|
398
|
+
end
|
399
|
+
|
400
|
+
attr_reader :entity_expansion_count
|
401
|
+
|
402
|
+
def record_entity_expansion
|
403
|
+
@entity_expansion_count += 1
|
404
|
+
if @entity_expansion_count > @@entity_expansion_limit
|
405
|
+
raise "number of entity expansions exceeded, processing aborted."
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
private
|
410
|
+
def build( source )
|
411
|
+
Parsers::TreeParser.new( source, self ).parse
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
class Text < Child
|
416
|
+
include Comparable
|
417
|
+
|
418
|
+
attr_accessor :raw
|
419
|
+
|
420
|
+
def initialize(arg, respect_whitespace=false, parent=nil, raw=nil,
|
421
|
+
entity_filter=nil )
|
422
|
+
|
423
|
+
@raw = false
|
424
|
+
|
425
|
+
if parent
|
426
|
+
super( parent )
|
427
|
+
@raw = parent.raw
|
428
|
+
else
|
429
|
+
@parent = nil
|
430
|
+
end
|
431
|
+
|
432
|
+
@raw = raw unless raw.nil?
|
433
|
+
@entity_filter = entity_filter
|
434
|
+
@normalized = @unnormalized = nil
|
435
|
+
|
436
|
+
if arg.kind_of? String
|
437
|
+
@string = arg.clone
|
438
|
+
@string.squeeze!(" \n\t") unless respect_whitespace
|
439
|
+
else
|
440
|
+
if arg.kind_of? Text
|
441
|
+
@string = arg.to_s
|
442
|
+
@raw = arg.raw
|
443
|
+
else
|
444
|
+
raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
@string.gsub!( /\r\n?/, "\n" )
|
449
|
+
end
|
450
|
+
|
451
|
+
def node_type
|
452
|
+
:text
|
453
|
+
end
|
454
|
+
|
455
|
+
def empty?
|
456
|
+
@string.size==0
|
457
|
+
end
|
458
|
+
|
459
|
+
|
460
|
+
def clone
|
461
|
+
return Text.new(self)
|
462
|
+
end
|
463
|
+
|
464
|
+
|
465
|
+
# Appends text to this text node. The text is appended in the +raw+ mode
|
466
|
+
# of this text node.
|
467
|
+
def <<( to_append )
|
468
|
+
@string << to_append.gsub( /\r\n?/, "\n" )
|
469
|
+
end
|
470
|
+
|
471
|
+
|
472
|
+
# +other+ a String or a Text
|
473
|
+
# +returns+ the result of (to_s <=> arg.to_s)
|
474
|
+
def <=>( other )
|
475
|
+
to_s() <=> other.to_s
|
476
|
+
end
|
477
|
+
|
478
|
+
def doctype
|
479
|
+
if @parent
|
480
|
+
doc = @parent.document
|
481
|
+
doc.doctype if doc
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
def to_s
|
486
|
+
@string
|
487
|
+
end
|
488
|
+
|
489
|
+
def inspect
|
490
|
+
@string.inspect
|
491
|
+
end
|
492
|
+
|
493
|
+
def value
|
494
|
+
#TODO:
|
495
|
+
#return @unnormalized if @unnormalized
|
496
|
+
#@unnormalized = Text::unnormalize( @string, doctype )
|
497
|
+
|
498
|
+
@string
|
499
|
+
end
|
500
|
+
|
501
|
+
#TODO optimize it - regular expressions is slow on BB
|
502
|
+
=begin
|
503
|
+
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
|
504
|
+
string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
|
505
|
+
ref = $&
|
506
|
+
if ref[1] == ?#
|
507
|
+
if ref[2] == ?x
|
508
|
+
[ref[3...-1].to_i(16)].pack('U*')
|
509
|
+
else
|
510
|
+
[ref[2...-1].to_i].pack('U*')
|
511
|
+
end
|
512
|
+
elsif ref == '&'
|
513
|
+
'&'
|
514
|
+
elsif filter and filter.include?( ref[1...-1] )
|
515
|
+
ref
|
516
|
+
elsif doctype
|
517
|
+
doctype.entity( ref[1...-1] ) or ref
|
518
|
+
else
|
519
|
+
entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
|
520
|
+
entity_value ? entity_value.value : ref
|
521
|
+
end
|
522
|
+
}
|
523
|
+
end
|
524
|
+
=end
|
525
|
+
end
|
526
|
+
|
527
|
+
end
|