wontomedia 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/COPYING +661 -0
  2. data/COPYING.DOCUMENTATION +450 -0
  3. data/LICENSE +661 -0
  4. data/README.markdown +56 -0
  5. data/Rakefile +185 -0
  6. data/VERSION.yml +4 -0
  7. data/app/controllers/admin_controller.rb +144 -0
  8. data/app/controllers/application_controller.rb +29 -0
  9. data/app/controllers/connections_controller.rb +150 -0
  10. data/app/controllers/items_controller.rb +365 -0
  11. data/app/helpers/connections_helper.rb +67 -0
  12. data/app/helpers/format_helper.rb +154 -0
  13. data/app/helpers/items_helper.rb +105 -0
  14. data/app/models/category_item.rb +23 -0
  15. data/app/models/connection.rb +210 -0
  16. data/app/models/individual_item.rb +23 -0
  17. data/app/models/item.rb +86 -0
  18. data/app/models/property_item.rb +23 -0
  19. data/app/models/qualified_item.rb +23 -0
  20. data/app/views/admin/index.html.erb +74 -0
  21. data/app/views/connections/_index_outbound_links.html.erb +48 -0
  22. data/app/views/connections/_spo_select_controls.html.erb +151 -0
  23. data/app/views/connections/edit.html.erb +70 -0
  24. data/app/views/connections/index.html.erb +84 -0
  25. data/app/views/connections/new.html.erb +61 -0
  26. data/app/views/connections/show.html.erb +110 -0
  27. data/app/views/items/_active_content.html.erb +26 -0
  28. data/app/views/items/_content_examples.html.erb +55 -0
  29. data/app/views/items/_core_tasks.html.erb +23 -0
  30. data/app/views/items/_form_fields.html.erb +69 -0
  31. data/app/views/items/_list_outbound_links.html.erb +58 -0
  32. data/app/views/items/_screen_select.html.erb +24 -0
  33. data/app/views/items/_show_outbound_links.html.erb +70 -0
  34. data/app/views/items/_topic_list.html.erb +26 -0
  35. data/app/views/items/_type_select.html.erb +47 -0
  36. data/app/views/items/edit.html.erb +63 -0
  37. data/app/views/items/index.html.erb +74 -0
  38. data/app/views/items/new.html.erb +124 -0
  39. data/app/views/items/newpop.html.erb +58 -0
  40. data/app/views/items/show.html.erb +209 -0
  41. data/app/views/layouts/_amazon_ads.html.erb +55 -0
  42. data/app/views/layouts/_glossary_help_box.html.erb +43 -0
  43. data/app/views/layouts/_google_ads.html.erb +40 -0
  44. data/app/views/layouts/_language_select.html.erb +24 -0
  45. data/app/views/layouts/_login_controls.html.erb +24 -0
  46. data/app/views/layouts/_master_help.html.erb +24 -0
  47. data/app/views/layouts/_navigation_menu.html.erb +39 -0
  48. data/app/views/layouts/_search_box.html.erb +27 -0
  49. data/app/views/layouts/_status_msgs.html.erb +25 -0
  50. data/app/views/layouts/application.html.erb +67 -0
  51. data/app/views/layouts/base.html.erb +93 -0
  52. data/app/views/layouts/home.html.erb +67 -0
  53. data/app/views/layouts/popup.html.erb +23 -0
  54. data/assets/wontomedia-sample.rb +47 -0
  55. data/config/asset_packages.yml +44 -0
  56. data/config/boot.rb +110 -0
  57. data/config/cucumber.yml +65 -0
  58. data/config/database-mysql-development.yml +47 -0
  59. data/config/database-mysql.yml +26 -0
  60. data/config/environment.rb +94 -0
  61. data/config/environments/cucumber.rb +29 -0
  62. data/config/environments/development.rb +26 -0
  63. data/config/environments/production.rb +33 -0
  64. data/config/environments/test.rb +31 -0
  65. data/config/initializers/inflections.rb +19 -0
  66. data/config/initializers/mime_types.rb +14 -0
  67. data/config/initializers/new_rails_defaults.rb +26 -0
  68. data/config/locales/en.yml +14 -0
  69. data/config/routes.rb +37 -0
  70. data/db/fixtures/connections.yml +96 -0
  71. data/db/fixtures/items.yml +277 -0
  72. data/db/migrate/20090312212805_create_items.rb +31 -0
  73. data/db/migrate/20090406221320_create_connections.rb +32 -0
  74. data/db/migrate/20090411014503_add_type_for_item_subclasses.rb +29 -0
  75. data/db/migrate/20090415142152_rename_item_type.rb +31 -0
  76. data/db/migrate/20090518022918_rename_object_and_self.rb +33 -0
  77. data/db/migrate/20090529171442_add_flags_to_items.rb +27 -0
  78. data/db/migrate/20090529171508_add_flags_to_connections.rb +27 -0
  79. data/db/migrate/20090605213800_flags_columns_not_null.rb +29 -0
  80. data/db/migrate/20090605215028_flags_columns_default_zero.rb +29 -0
  81. data/db/schema.rb +30 -0
  82. data/default-custom/app/views/items/_home_extern_list.html.erb +32 -0
  83. data/default-custom/app/views/items/_home_introductory_text.html.erb +70 -0
  84. data/default-custom/app/views/items/home.html.erb +77 -0
  85. data/default-custom/public/images/logo.png +0 -0
  86. data/default-custom/public/images/logo.svg +74 -0
  87. data/default-custom/public/stylesheets/wm.css +301 -0
  88. data/doc/README.markdown +44 -0
  89. data/doc/README_FOR_APP +82 -0
  90. data/doc/customization.markdown +93 -0
  91. data/doc/scripts/rake-customize.markdown +83 -0
  92. data/lib/helpers/connection_helper.rb +41 -0
  93. data/lib/helpers/item_helper.rb +141 -0
  94. data/lib/helpers/tripple_navigation.rb +158 -0
  95. data/lib/tasks/cucumber.rake +83 -0
  96. data/lib/tasks/customize.rake +70 -0
  97. data/lib/tasks/db.rake +65 -0
  98. data/lib/tasks/javascript_testing_tasks.rake +176 -0
  99. data/public/404.html +50 -0
  100. data/public/422.html +50 -0
  101. data/public/500.html +53 -0
  102. data/public/dispatch.cgi +20 -0
  103. data/public/dispatch.fcgi +34 -0
  104. data/public/dispatch.rb +20 -0
  105. data/public/favicon.ico +0 -0
  106. data/public/images/blank_error_icon.png +0 -0
  107. data/public/images/blank_status_icon.png +0 -0
  108. data/public/images/error_error_icon.png +0 -0
  109. data/public/images/error_status_icon.png +0 -0
  110. data/public/images/good_status_icon.png +0 -0
  111. data/public/images/help_icon.png +0 -0
  112. data/public/images/twitter_icon.png +0 -0
  113. data/public/images/warn_error_icon.png +0 -0
  114. data/public/images/working_status_icon.gif +0 -0
  115. data/public/javascripts/application.js +56 -0
  116. data/public/javascripts/controls.js +963 -0
  117. data/public/javascripts/dragdrop.js +973 -0
  118. data/public/javascripts/effects.js +1128 -0
  119. data/public/javascripts/event.simulate.js +64 -0
  120. data/public/javascripts/fancybox.js +43 -0
  121. data/public/javascripts/forConnectionsForms.js +218 -0
  122. data/public/javascripts/forItemsForms.js +511 -0
  123. data/public/javascripts/itemCreatePopup.js +115 -0
  124. data/public/javascripts/itemTitleToName.js +119 -0
  125. data/public/javascripts/jquery.js +4376 -0
  126. data/public/javascripts/modalbox.js +502 -0
  127. data/public/javascripts/prototype.js +4320 -0
  128. data/public/javascripts/reconcileJQueryAndPrototype.js +19 -0
  129. data/public/robots.txt +7 -0
  130. data/public/stylesheets/blank.gif +0 -0
  131. data/public/stylesheets/fancy_close.png +0 -0
  132. data/public/stylesheets/fancy_loading.png +0 -0
  133. data/public/stylesheets/fancy_nav_left.png +0 -0
  134. data/public/stylesheets/fancy_nav_right.png +0 -0
  135. data/public/stylesheets/fancy_shadow_e.png +0 -0
  136. data/public/stylesheets/fancy_shadow_n.png +0 -0
  137. data/public/stylesheets/fancy_shadow_ne.png +0 -0
  138. data/public/stylesheets/fancy_shadow_nw.png +0 -0
  139. data/public/stylesheets/fancy_shadow_s.png +0 -0
  140. data/public/stylesheets/fancy_shadow_se.png +0 -0
  141. data/public/stylesheets/fancy_shadow_sw.png +0 -0
  142. data/public/stylesheets/fancy_shadow_w.png +0 -0
  143. data/public/stylesheets/fancy_title_left.png +0 -0
  144. data/public/stylesheets/fancy_title_main.png +0 -0
  145. data/public/stylesheets/fancy_title_over.png +0 -0
  146. data/public/stylesheets/fancy_title_right.png +0 -0
  147. data/public/stylesheets/fancybox.css +333 -0
  148. data/public/stylesheets/modalbox.css +110 -0
  149. data/public/stylesheets/scaffold.css +36 -0
  150. data/public/stylesheets/spinner.gif +0 -0
  151. data/script/about +4 -0
  152. data/script/console +3 -0
  153. data/script/cucumber +10 -0
  154. data/script/dbconsole +3 -0
  155. data/script/destroy +3 -0
  156. data/script/generate +3 -0
  157. data/script/performance/benchmarker +3 -0
  158. data/script/performance/profiler +3 -0
  159. data/script/performance/request +3 -0
  160. data/script/plugin +3 -0
  161. data/script/process/inspector +3 -0
  162. data/script/process/reaper +3 -0
  163. data/script/process/spawner +3 -0
  164. data/script/runner +3 -0
  165. data/script/server +3 -0
  166. data/vendor/plugins/asset_packager/CHANGELOG +122 -0
  167. data/vendor/plugins/asset_packager/README +178 -0
  168. data/vendor/plugins/asset_packager/Rakefile +22 -0
  169. data/vendor/plugins/asset_packager/about.yml +8 -0
  170. data/vendor/plugins/asset_packager/init.rb +2 -0
  171. data/vendor/plugins/asset_packager/install.rb +1 -0
  172. data/vendor/plugins/asset_packager/lib/jsmin.rb +205 -0
  173. data/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb +212 -0
  174. data/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb +39 -0
  175. data/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake +23 -0
  176. data/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb +100 -0
  177. data/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb +140 -0
  178. data/vendor/plugins/asset_packager/test/asset_packager_test.rb +92 -0
  179. data/vendor/plugins/asset_packager/test/asset_packages.yml +20 -0
  180. data/vendor/plugins/asset_packager/test/assets/javascripts/application.js +2 -0
  181. data/vendor/plugins/asset_packager/test/assets/javascripts/bar.js +4 -0
  182. data/vendor/plugins/asset_packager/test/assets/javascripts/controls.js +815 -0
  183. data/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js +913 -0
  184. data/vendor/plugins/asset_packager/test/assets/javascripts/effects.js +958 -0
  185. data/vendor/plugins/asset_packager/test/assets/javascripts/foo.js +4 -0
  186. data/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js +2006 -0
  187. data/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css +16 -0
  188. data/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css +16 -0
  189. data/vendor/plugins/asset_packager/test/assets/stylesheets/header.css +16 -0
  190. data/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css +16 -0
  191. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css +16 -0
  192. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css +16 -0
  193. metadata +265 -0
@@ -0,0 +1,365 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ #### I've got no idea why this 'require' is necessary. Without it, all
22
+ # the unit tests pass, but the ItemHelper.nouns call below fails when
23
+ # run in production. Even more odd, if run in 'development' (so that
24
+ # each Ruby file is reloaded at each request, this 'require' only has
25
+ # to be present for the _first_ request serviced after the server
26
+ # starts. It can be deleted, this file reloaded, and then ItemHelper
27
+ # references will work normally. Go figure. -- gei 2010/2/24
28
+ require Rails.root.join( 'lib', 'helpers', 'item_helper')
29
+ require 'yaml'
30
+
31
+ # See also the matching model Item
32
+ class ItemsController < ApplicationController
33
+ # GET /
34
+ def home
35
+ @nouns = ItemHelper.nouns
36
+ render :layout => "home"
37
+ end
38
+
39
+ # GET /items
40
+ #
41
+ # Note that +index+ is capable of rendering in multiple
42
+ # formats. <tt>/items</tt> and <tt>/items.html</tt> yield a
43
+ # human-readable page in HTML markup. <tt>/items.yaml</tt> renders
44
+ # all fields from all Items in the database as YAML-format text,
45
+ # with no additional prose or links intended for users.
46
+ def index
47
+ @items = Item.all.reverse
48
+ @not_in_use_hash = {}
49
+ @items.each do |item|
50
+ @not_in_use_hash[item.id] =
51
+ Connection.all( :conditions =>
52
+ [ "subject_id = ? OR predicate_id = ? OR obj_id = ?",
53
+ item.id, item.id, item.id ]).
54
+ empty?
55
+ end
56
+
57
+ respond_to do |wants|
58
+ wants.html
59
+ wants.yaml do
60
+ render :text =>
61
+ @items.reject { |item|
62
+ (item.flags & Item::DATA_IS_UNALTERABLE) != 0 }.
63
+ to_yaml
64
+ end
65
+ end
66
+ end
67
+
68
+ # GET /items/new
69
+ def new
70
+ @this_is_non_information_page = true
71
+ @item = Item.new
72
+ end
73
+
74
+ # GET /items/new-pop
75
+ #
76
+ # This operation is intended to provide a version of
77
+ # <tt>/items/new</tt> suitable for Ajax fetching fromm and display
78
+ # in a pop-up <tt><div></tt> in an already-rendered page. Correct
79
+ # operation of the page fragment rendered by this action depends on
80
+ # the surrounding page having already loaded the form's JavaScript
81
+ # and style dependencies. Implementing this behavior depends on the
82
+ # <tt>popup_flag</tt> field passed between Items +actions+ and
83
+ # +views+; see their source for additional details.
84
+ def newpop
85
+ @item = Item.new
86
+ @type = params[:type]
87
+ render :layout => "popup"
88
+ end
89
+
90
+ # POST /items
91
+ def create
92
+ type_string = params[:item][:sti_type]
93
+ params[:item].delete :sti_type # don't mass-assign protected blah, blah
94
+ @item = ItemHelper.new_typed_item(type_string, params[:item])
95
+ @popup_flag = true if params[:popup_flag]
96
+
97
+ if @item.nil?
98
+ flash.now[:error] =
99
+ 'Could not create. Item must have a type of either "Category" or "Individual".'
100
+ @item = Item.new(params[:item]) # keep info already entered
101
+ @item.sti_type = type_string
102
+ @this_is_non_information_page = true
103
+ render :action => (@popup_flag ? "newpop" : "new" )
104
+ elsif @item.name =~ /[:.]/ || !@item.save
105
+ @item.errors.add :name, "cannot contain a period (.) or a colon (:)."
106
+ @this_is_non_information_page = true
107
+ render :action => (@popup_flag ? "newpop" : "new" )
108
+ else
109
+ if @popup_flag
110
+ @connection_list = []; @item_hash = {}; @connection_hash = {}
111
+ flash.now[:notice] = 'Item was successfully created.'
112
+ render :action => "show", :layout => "popup"
113
+ else
114
+ flash[:notice] = 'Item was successfully created.'
115
+ redirect_to item_path(@item)
116
+ end
117
+ end
118
+ end
119
+
120
+ # GET /items/1
121
+ #
122
+ # Note that +show+ is capable of rendering in multiple
123
+ # formats. <tt>/items/1</tt> and <tt>/items/1.html</tt> yield a
124
+ # human-readable page in HTML markup. <tt>/items/1.json</tt>
125
+ # renders all fields from the specified Item as JSON-format text,
126
+ # with no additional prose or links intended for users. In the JSON
127
+ # case, only information about the specific Item requested is
128
+ # returned. When a full web page is generated, information is
129
+ # included about all other Items which are involved in Connections
130
+ # that directly reference the requested Item.
131
+ def show
132
+ begin
133
+ @item = Item.find(params[:id])
134
+ rescue
135
+ render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
136
+ return
137
+ end
138
+
139
+ if request.format.json?
140
+ # huge kludge for testability. Need to ensure that we don't respond
141
+ # so quickly (e.g., in setups where client and server are on the same
142
+ # system) that the JavaScript and acceptance tests can't see the
143
+ # "request in progress" state of the page/system.
144
+ if (RAILS_ENV == 'test')
145
+ Kernel.sleep(0.75)
146
+ end
147
+
148
+ render :json => @item
149
+ return
150
+ end
151
+
152
+ used_as_subj = Connection.all( :conditions =>
153
+ [ "subject_id = ?", @item.id ])
154
+ used_as_pred = Connection.all( :conditions =>
155
+ [ "predicate_id = ?", @item.id ])
156
+ used_as_obj = Connection.all( :conditions =>
157
+ [ "obj_id = ?", @item.id ])
158
+
159
+ @item_hash = {}
160
+ @connection_hash = {}
161
+ [ used_as_subj, used_as_pred, used_as_obj ].each do |connection_array|
162
+ connection_array.each do |connection|
163
+ unless @connection_hash.has_key? connection.id
164
+ @connection_hash[connection.id] = connection
165
+ [ connection.subject, connection.predicate, connection.obj ].
166
+ each do |item|
167
+ unless @item_hash.has_key? item.id
168
+ @item_hash[item.id] = item
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ # now that we've got all the connections to display, order and group them
176
+ # @connection_list should be an array of arrays, each internal array is
177
+ # a "section" of the display page, containing .id's of connections
178
+ @connection_list = []
179
+
180
+ value_id = Item.find_by_name("value_relationship").id
181
+ spo_id = Item.find_by_name("sub_property_of").id
182
+
183
+ # first group, all connections *from* this item with value-type predicates
184
+ connections = []
185
+ connections_to_delete = []
186
+ used_as_subj.each do |connection|
187
+ if TrippleNavigation.check_properties(
188
+ :does => connection.predicate_id, :via => spo_id,
189
+ :inherit_from => value_id )
190
+ connections << connection.id
191
+ connections_to_delete << connection
192
+ end
193
+ end
194
+ used_as_subj -= connections_to_delete # done incrementally, breaks iterator
195
+ unless connections.empty?
196
+ @connection_list << connections
197
+ end
198
+
199
+
200
+ # next N groups: 1 group for connections *from* this item with >1 of
201
+ # same pred.
202
+ #figure out which predicates occur >1, how many they occur, sort & group
203
+ pred_counts = {}
204
+ connection_using_pred = {}
205
+ used_as_subj.each do |connection|
206
+ if pred_counts[connection.predicate_id].nil?
207
+ pred_counts[connection.predicate_id] = 1
208
+ else
209
+ pred_counts[connection.predicate_id] += 1
210
+ end
211
+ connection_using_pred[connection.predicate_id] = connection.id
212
+ end
213
+ subj_connections = pred_counts.keys
214
+ subj_connections.sort! { |a,b| pred_counts[b] <=> pred_counts[a] }
215
+ array_of_singles = []
216
+ subj_connections.each do |predicate_id|
217
+ if pred_counts[predicate_id] > 1
218
+ connections = []
219
+ used_as_subj.each do |connection|
220
+ # lazy, more hashes would eliminate rescan
221
+ if connection.predicate_id == predicate_id
222
+ connections << connection.id
223
+ end
224
+ end
225
+ unless connections.empty?
226
+ @connection_list << connections
227
+ end
228
+ else
229
+ array_of_singles << connection_using_pred[predicate_id]
230
+ end
231
+ end
232
+
233
+ # last group of connections *from* current item:
234
+ # all connections w/ used-once pred's
235
+ unless array_of_singles.empty?
236
+ @connection_list << array_of_singles
237
+ end
238
+
239
+
240
+ obj_connections = used_as_obj.map { |connection| connection.id }
241
+ obj_connections.sort! do |a,b|
242
+ if @connection_hash[a].predicate_id == @connection_hash[b].predicate_id
243
+ @connection_hash[a].obj_id <=> @connection_hash[b].obj_id
244
+ else
245
+ @connection_hash[a].predicate_id <=> @connection_hash[b].predicate_id
246
+ end
247
+ end
248
+ unless obj_connections.empty?
249
+ @connection_list << obj_connections
250
+ end
251
+
252
+
253
+ pred_connections = used_as_pred.map { |connection| connection.id }
254
+ unless pred_connections.empty?
255
+ @connection_list << pred_connections
256
+ end
257
+ end
258
+
259
+ # GET /items/1/edit
260
+ def edit
261
+ begin
262
+ @this_is_non_information_page = true
263
+ @item = Item.find(params[:id])
264
+ rescue
265
+ render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
266
+ return
267
+ end
268
+ end
269
+
270
+ # PUT /items/1
271
+ def update
272
+ # we want to be agnostic WRT processing item subclasses, so remap
273
+ # name of incoming parameters if we're actually handling a child
274
+ params.each do |k,v|
275
+ if k =~ /_item/
276
+ params["item"] = v
277
+ end
278
+ end
279
+
280
+ begin
281
+ @item = ItemHelper.find_typed_item(params[:id])
282
+ rescue
283
+ render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
284
+ return
285
+ end
286
+
287
+ if (@item.flags & Item::DATA_IS_UNALTERABLE) != 0
288
+ flash[:error] = 'This Item cannot be altered.'
289
+ redirect_to item_path(@item)
290
+ elsif (!params[:item].nil? && !params[:item][:name].nil? &&
291
+ params[:item][:name] =~ /[:.]/ ) ||
292
+ !@item.update_attributes(params[:item])
293
+ @item.errors.add :name, "cannot contain a period (.) or a colon (:)."
294
+ @this_is_non_information_page = true
295
+ render :action => "edit"
296
+ else
297
+ flash[:notice] = 'Item was successfully updated.'
298
+ redirect_to item_path(@item)
299
+ end
300
+ end
301
+
302
+ # DELETE /items/1
303
+ def destroy
304
+ begin
305
+ @item = Item.find(params[:id])
306
+ rescue
307
+ render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
308
+ return
309
+ end
310
+
311
+ if (@item.flags & Item::DATA_IS_UNALTERABLE) != 0
312
+ flash[:error] = 'This Item cannot be altered.'
313
+ redirect_to item_path(@item)
314
+ elsif !(Connection.all( :conditions =>
315
+ [ "subject_id = ? OR predicate_id = ? OR obj_id = ?",
316
+ @item.id, @item.id, @item.id ]).empty?)
317
+ flash[:error] = 'This Item is in use by 1+ Connections. ' +
318
+ 'Those must be modified or deleted first.'
319
+ redirect_to item_path(@item)
320
+ else
321
+ @item.destroy
322
+ redirect_to items_url
323
+ end
324
+ end
325
+
326
+ # GET /items/lookup?name=anItemName
327
+ #
328
+ # This operation is similar to an abbreviated +show+. It always
329
+ # sends an HTML fragment (not a complete/valid page) to the
330
+ # requester, either an error message (plus <tt>:status => 404</tt>,
331
+ # if the requested item doesn't exist) or a string representation of
332
+ # the Item's +id+ field (plus <tt>:status => 200</tt>). While this
333
+ # is technically a RESTful request, it uses a string (rather than a
334
+ # database ID number as is the default for Rails requests) as the
335
+ # request parameter, and the parameter is encoded in the query
336
+ # string portion of the URL (rather than the path portion, in order
337
+ # to simplify creation of the matching route).
338
+ #
339
+ # This request is primarily intended to be used by Ajax code
340
+ # executing within another page that has already been served by
341
+ # WontoMedia.
342
+ def lookup
343
+ # huge kludge for testability. Need to ensure that we don't respond
344
+ # so quickly (e.g., in setups where client and server are on the same
345
+ # system) that the JavaScript and acceptance tests can't see the
346
+ # "request in progress" state of the page/system.
347
+ if (RAILS_ENV == 'test')
348
+ Kernel.sleep(0.75)
349
+ end
350
+
351
+ begin
352
+ item = Item.find_by_name(params[:name])
353
+ if item.nil?
354
+ render :text => "<p>Didn't find Item</p>\n", :status => 404
355
+ return
356
+ end
357
+ id = item.id
358
+ rescue
359
+ render :text => "<p>Didn't find Item</p>\n", :status => 404
360
+ return
361
+ end
362
+
363
+ render :text => ("<id>" + id.to_s + "</id>\n")
364
+ end
365
+ end
@@ -0,0 +1,67 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ # Helpers for app/views/connections/* pages
22
+ module ConnectionsHelper
23
+
24
+ # This method appends its output directly to the page being built.
25
+ # It takes a Connection model instance, and generates a set of HTML
26
+ # links to that connection. It generates a "Show" link to the
27
+ # Connection's <tt>connections/show</tt> page. Unless the
28
+ # Connection is flagged as <tt>DATA_IS_UNALTERABLE</tt>, it also
29
+ # generates an "Edit..." link to +con+'s <tt>connections/edit</tt>
30
+ # page and a "Delete" link that will invoke
31
+ # <tt>connections/destroy</tt>. The links are generated with a
32
+ # "help" icon linking to a popup (see
33
+ # FormatHelper.link_with_help_icon) _if_ the link being generated is
34
+ # the first occurrance of that link in the current view. An instance
35
+ # variable is created within the current view object to flag the
36
+ # generation of each type of link.
37
+ def generate_connection_links(con)
38
+ concat(
39
+ link_with_help_icon({
40
+ :destination => link_to( 'Show', connection_path(con) ),
41
+ :already_generated => @show_help_icon_used,
42
+ :help_alt => 'Help show connection',
43
+ :which_help => 'ConnectionShow' }) )
44
+ @show_help_icon_used = true
45
+
46
+ if (con.flags & Connection::DATA_IS_UNALTERABLE) == 0
47
+ concat(
48
+ link_with_help_icon({
49
+ :destination => link_to(
50
+ 'Edit&hellip;', edit_connection_path(con), :rel => 'nofollow' ),
51
+ :already_generated => @edit_help_icon_used,
52
+ :help_alt => 'Help edit connection',
53
+ :which_help => 'ConnectionEdit' }) )
54
+ @edit_help_icon_used = true
55
+
56
+ concat(
57
+ link_with_help_icon({
58
+ :destination => link_to(
59
+ 'Delete', connection_path(con), :rel => 'nofollow',
60
+ :confirm => 'Are you sure?', :method => :delete ),
61
+ :already_generated => @delete_help_icon_used,
62
+ :help_alt => 'Help delete connection',
63
+ :which_help =>'ConnectionDelete' }) )
64
+ @delete_help_icon_used = true
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,154 @@
1
+ #--
2
+ # WontoMedia - a wontology web application
3
+ # Copyright (C) 2010 - Glen E. Ivey
4
+ # www.wontology.com
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License version
8
+ # 3 as published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program in the file COPYING and/or LICENSE. If not,
17
+ # see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+
21
+ # This module contains a collection of page- and model-independent
22
+ # formatting methods. All return a string suitable for including
23
+ # directly in a page.
24
+ module FormatHelper
25
+
26
+ # This method takes in a string, and returns a version of it
27
+ # excluding any sub-strings enclosed in parentheticals. Nested and
28
+ # multiple parentheticals are supported. This method is intended to
29
+ # support the WontoMedia behavior where sometimes an Item.title
30
+ # string is displayed in its entirety, and sometimes it is
31
+ # abbreviated (for space) by stripping any parentheticals it contains.
32
+ def filter_parenthetical(title_in)
33
+ local_copy = title_in
34
+ begin
35
+ title_out = local_copy
36
+ local_copy = local_copy.sub(/\s*\([^()]*\)/, "")
37
+ end until local_copy == title_out
38
+ title_out
39
+ end
40
+
41
+ # This method is used to wrap long strings that don't contain spaces
42
+ # (which would allow the browser to wrap them), such as an
43
+ # <tt>Item.name</tt> string. The +len+ parameter is a length in
44
+ # _characters_, and the default is tuned to produce reasonably good
45
+ # results in the table in the items/index page. The return value is
46
+ # an HTML snippet including a marker to indicate that wrapping has
47
+ # occurred.
48
+ #--
49
+ # TODO: It would be better if wrapping were done
50
+ # dynamically in JavaScript as the page is resized, as sometimes
51
+ # wrapping the string statically doesn't produce a really great
52
+ # result. Of course, to really do it right, we'd rewrap any time
53
+ # the page width is adjusted, and use the actual width of the text
54
+ # (rather than character count) as the basis for wrapping.
55
+ def wrap_item_name(name, len = 30)
56
+ wrapped = ''
57
+ [ len, len*2, len*3, len*4 ].each do |wrap_at|
58
+ wrapped += name[wrap_at - len, len].to_s
59
+ if name.length > wrap_at
60
+ wrapped += '<span class="wrapper"> &gt;&gt;&gt;</span><br />'
61
+ end
62
+ end
63
+ wrapped
64
+ end
65
+
66
+ # This method generates an HTML snipet for an icon that will cause a
67
+ # pop-up help box to be displayed when clicked. This helper is tied
68
+ # very tightly to WontoMedia's style sheet, included JavaScript
69
+ # libraries, and image assets. The parameters are used as follows:
70
+ #
71
+ # [alt] This string is used as the 'alt' attribute for the <img> tag that is generated, and allows each help image/link generated by this helper to have unique alt text that describes the kind of help the link points to.
72
+ # [target] This string specifies the source of the help page that should be rendered into the popup <iframe>. A complete URL is created by appending the value of +target+ to the configuration value <tt>WontoMedia.popup_url_prefix</tt> from the file <tt>config/initializers/wontomedia.rb</tt>.
73
+ # [text] The content of this string, if any, is placed immediately _before_ the popup help icon (the <img> tag) that this helper generates. This text is not part of the link that will cause the help popup to be opened. When present, the value is packaged along with the help icon in a <span> with the <tt>nowrap</tt> style. This will prevent the browser from separating the help icon from the label that precedes it due to text wrapping. If this argument is <tt>nil</tt>, then no span is generated. An empty string will produce a span with no content aside from the generated link.
74
+ def popup_help_icon( alt, target, text = nil )
75
+ content = ''
76
+ if text
77
+ content += '<span style="white-space: nowrap;">' + text
78
+ end
79
+ content += link_to(
80
+ (
81
+ image_tag( 'help_icon.png', :alt=>alt, :class=>'image-in-text' ) +
82
+ '<span class="tip">Help</span>'
83
+ ),
84
+ WontoMedia.popup_url_prefix + target, :tabindex => '0',
85
+ :class => 'iframeBox linkhastip' )
86
+ if text
87
+ content += '</span>'
88
+ end
89
+ content
90
+ end
91
+
92
+ # This method wraps a block of text in HTML markup that provides it
93
+ # with a (CSS-based) 'tooltip'-like popup on mouse-over. The
94
+ # arguments are:
95
+ #
96
+ # [text] The text string to wrap and make sensitive to mouse-over. It may contain additional HTML markup, but cannot contain outbound links (e.g., <tt><a href=...></tt>).
97
+ # [tip] The content for the popup 'tooltip'. This may also contain HTML markup, but links should be avoided because of both usability considerations (moving the mouse within the tooltip can be challenging because it could go away if the cursors path strays outside the union of the text's and tip's bounding boxes) and the fact that some browsers will confuse links in the tooltip with the dummy link tag that this helper creates.
98
+ # [id] This helper creates a <tt><span></tt> tag around the supplied +text+. If +id+ is non-+nil+, its value will be used to create an +id+ attribute for the span.
99
+ def text_with_tooltip( text, tip, id = nil )
100
+ span = id.nil? ? '<span>' : "<span id='#{id}'>"
101
+ inner = "#{span}#{text}</span>" +
102
+ "<span class='tip' style='white-space: nowrap;'>#{tip}</span>"
103
+ link_to inner, "#", :class=>'texthastip', :tabindex=>'0'
104
+ end
105
+
106
+ # This method creates a link wraped in HTML markup that provides it
107
+ # with a (CSS-based) 'tooltip'-like popup on mouse-over. The
108
+ # arguments are:
109
+ #
110
+ # [text] The content for the link (anchor tag) generated. It may be any HTML string that would be valid within a link.
111
+ # [tip] The content for the popup 'tooltip'. This may also contain HTML markup, but links should be avoided because of both usability considerations (moving the mouse within the tooltip can be challenging because it could go away if the cursors path strays outside the union of the text's and tip's bounding boxes) and the fact that some browsers will confuse links in the tooltip with the link that causes the tooltip to be displayed.
112
+ # [href] The value of this argument will be used to generate the +href+ attribute of the link created. It is passed directly to Rails' <tt>link_to</tt> helper, so any string, or Rails object or route that can be converted to a URL can be used.
113
+ # [id] This helper creates a <tt><span></tt> tag around the content of the +text+ argument. If +id+ is non-+nil+, its value will be used to create an +id+ attribute for the span.
114
+ def link_with_tooltip( text, tip, href, id = nil )
115
+ span = id.nil? ? '<span>' : "<span id='#{id}'>"
116
+ inner = "#{span}#{text}</span>" +
117
+ "<span class='tip' style='white-space: nowrap;'>#{tip}</span>"
118
+ link_to inner, href, :class=>'linkhastip', :tabindex=>'0'
119
+ end
120
+
121
+ # This helper constructs a text link optionally followed by an image
122
+ # link which, when clicked, will open a popup box in the window
123
+ # populated by a page from the installation's help wiki. The markup
124
+ # generated ensures that word-wrap in the browser will not separate
125
+ # the help icon from the link that precedes it. The helper's
126
+ # parameters are packaged in a single hash argument. The symbols
127
+ # used to index the argument hash are:
128
+ #
129
+ # [:destination] The value in the hash associated with <tt>:destination</tt> should be a complete HTML link, such as the return value from the Rails' helper <tt>link_to</tt>.
130
+ # [:already_generated] The value in the hash associated with <tt>:already_generated</tt> will be evaluated as a boolean to determine whether a popup help icon (image link) should be generated by this call to link_with_help_icon. When it evaluates to false/nil (including simply not being present in the argument hash at all), HTML for a help icon _is_ generated/returned.
131
+ # [:help_alt] The string in the hash associated with <tt>:help_alt</tt> will be used as the value for the +alt+ attribute of the anchor tag for the help icon/link (if generated). (The +alt+ tag, if any, for <tt>:destination</tt> should be incorporated in the link's markup before it is passed to this helper.)
132
+ # [:which_help] The string in the hash associated with <tt>:which_help</tt> is used as a component in the URL to the desired page from the installation's help wiki. It is combined with the installation's popup_url_prefix configuration value (see popup_help_icon) after being prefixed with <tt>Help:Popup/</tt>. That is, this helper assumes that within the help wiki, the content for all help displayed in a popup box in the page is stored as a <em>sub-page</em> of the help wiki's page +Popup+ within the wiki's namespace +Help+.
133
+ # [:text] The _optional_ value in the hash associated with <tt>:text</tt> will, if present, be included in the generated HTML between the content of <tt>:destination</tt> and the generated help icon. See the +text+ argument to popup_help_icon.
134
+ def link_with_help_icon( params )
135
+ help_link = ''
136
+ unless params[:already_generated]
137
+ unless params.has_key?(:help_alt)
138
+ raise ArgumentError, "Missing :help_alt entry from parameter hash"
139
+ end
140
+ unless params.has_key?(:which_help)
141
+ raise ArgumentError, "Missing :which_help entry from parameter hash"
142
+ end
143
+
144
+ help_link = popup_help_icon params[:help_alt],
145
+ ("Help:Popup/" + params[:which_help]), params[:text]
146
+ end
147
+
148
+ unless params.has_key?(:destination)
149
+ raise ArgumentError, "Missing :destination entry from parameter hash"
150
+ end
151
+ return content_tag( 'span', params[:destination] + help_link,
152
+ :style => "white-space: nowrap;" ) + " "
153
+ end
154
+ end