wagn 1.14.4 → 1.14.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/app/controllers/card_controller.rb +4 -3
- data/db/bootstrap/card_actions.yml +597 -583
- data/db/bootstrap/card_acts.yml +2 -2
- data/db/bootstrap/card_changes.yml +297 -248
- data/db/bootstrap/card_references.yml +3111 -1284
- data/db/bootstrap/cards.yml +1067 -1022
- data/db/migrate_core_cards/20141208132416_partial_reference_type.rb +7 -0
- data/db/migrate_core_cards/20141208162106_add_ace_script.rb +12 -0
- data/db/migrate_core_cards/20141230204340_uri_codename.rb +13 -0
- data/db/version_core_cards.txt +1 -1
- data/features/history.feature +2 -1
- data/features/layouts.feature +4 -0
- data/features/navbox.feature +1 -0
- data/features/step_definitions/wagn_steps.rb +6 -1
- data/features/support/env.rb +1 -1
- data/lib/card/env.rb +1 -1
- data/lib/card/format.rb +35 -48
- data/lib/card/loader.rb +9 -9
- data/lib/card/mailer.rb +0 -2
- data/lib/card/query.rb +8 -8
- data/lib/card/query/{card_spec.rb → card_clause.rb} +42 -42
- data/lib/card/query/{spec.rb → clause.rb} +3 -3
- data/lib/card/query/ref_clause.rb +47 -0
- data/lib/card/query/value_clause.rb +65 -0
- data/lib/card/reference.rb +11 -20
- data/lib/card/set.rb +6 -6
- data/lib/card/set_pattern.rb +5 -1
- data/lib/wagn/commands.rb +28 -14
- data/lib/wagn/config/environments/test.rb +3 -0
- data/lib/wagn/generators/wagn/templates/Gemfile +6 -0
- data/lib/wagn/generators/wagn/templates/Rakefile +1 -0
- data/lib/wagn/generators/wagn/templates/config/application.rb +1 -0
- data/lib/wagn/generators/wagn/templates/spec/javascripts/support/deck_jasmine.yml +56 -0
- data/lib/wagn/generators/wagn/templates/spec/javascripts/support/wagn_jasmine.yml +69 -0
- data/lib/wagn/generators/wagn/wagn_generator.rb +19 -2
- data/lib/wagn/migration.rb +10 -0
- data/lib/wagn/spec_helper.rb +2 -0
- data/lib/wagn/tasks/wagn.rake +9 -16
- data/mod/01_core/chunk/link.rb +2 -2
- data/mod/01_core/chunk/uri.rb +4 -4
- data/mod/01_core/format/html_format.rb +43 -280
- data/mod/01_core/set/all/active_card.rb +2 -0
- data/mod/01_core/set/all/collection.rb +19 -1
- data/mod/01_core/set/all/fetch.rb +5 -0
- data/mod/01_core/set/all/initialize.rb +1 -1
- data/mod/01_core/set/all/references.rb +25 -8
- data/mod/01_core/set/all/templating.rb +1 -1
- data/mod/01_core/set/all/tracked_attributes.rb +1 -1
- data/mod/01_core/set/all/type.rb +1 -1
- data/mod/01_core/set/all/utils.rb +1 -0
- data/mod/01_core/set_pattern/07_type_plus_right.rb +2 -1
- data/mod/01_core/spec/format/html_format_spec.rb +0 -2
- data/mod/01_core/spec/set/all/initialize_spec.rb +4 -4
- data/mod/01_core/spec/set/all/notify_spec.rb +9 -9
- data/mod/02_basic_types/set/type/pointer.rb +19 -8
- data/mod/03_machines/lib/javascript/ace.js +18204 -0
- data/mod/03_machines/lib/javascript/jquery-ui.js +13109 -11440
- data/mod/03_machines/lib/javascript/jquery.autosize.js +52 -33
- data/mod/03_machines/lib/javascript/jquery.fileupload.js +10 -8
- data/mod/03_machines/lib/javascript/jquery.iframe-transport.js +44 -16
- data/mod/03_machines/lib/javascript/jquery.js +4 -9473
- data/mod/03_machines/lib/javascript/jquery_ujs.js +156 -116
- data/mod/03_machines/lib/javascript/jquerymobile.js +14890 -8236
- data/mod/03_machines/lib/javascript/theme-textmate.js +130 -0
- data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +50 -10
- data/mod/03_machines/set/self/script_ace.rb +8 -0
- data/mod/03_machines/set/type/coffee_script.rb +1 -1
- data/mod/03_machines/set/type/css.rb +0 -2
- data/mod/03_machines/set/type/java_script.rb +1 -1
- data/mod/03_machines/spec/lib/{machine_spec.rb → shared_machine_examples.rb} +0 -0
- data/mod/03_machines/spec/lib/{machine_input_spec.rb → shared_machine_input_examples.rb} +0 -0
- data/mod/03_machines/spec/set/type/scss_spec.rb +2 -2
- data/mod/04_settings/set/right/comment.rb +2 -2
- data/mod/04_settings/set/type/setting.rb +2 -2
- data/mod/04_settings/spec/set/right/structure_spec.rb +2 -2
- data/mod/04_settings/spec/set/right/style_spec.rb +1 -1
- data/mod/05_email/set/type/email_template.rb +3 -2
- data/mod/05_standard/set/all/all_css.rb +1 -1
- data/mod/05_standard/set/all/all_js.rb +1 -1
- data/mod/05_standard/set/all/attach.rb +8 -7
- data/mod/05_standard/set/all/base.rb +6 -34
- data/mod/05_standard/set/all/editing.rb +145 -0
- data/mod/05_standard/set/all/error.rb +203 -0
- data/mod/05_standard/set/all/follow.rb +2 -2
- data/mod/05_standard/set/all/form.rb +211 -0
- data/mod/05_standard/set/all/header.rb +60 -0
- data/mod/05_standard/set/all/history.rb +3 -3
- data/mod/05_standard/set/all/links.rb +101 -0
- data/mod/05_standard/set/all/rich_html.rb +14 -392
- data/mod/05_standard/set/all/wrapper.rb +74 -0
- data/mod/05_standard/set/right/account.rb +1 -2
- data/mod/05_standard/set/rstar/rules.rb +5 -5
- data/mod/05_standard/set/self/account_links.rb +8 -4
- data/mod/05_standard/set/self/head.rb +3 -3
- data/mod/05_standard/set/self/signin.rb +5 -3
- data/mod/05_standard/set/type/search_type.rb +25 -25
- data/mod/05_standard/set/type/set.rb +2 -2
- data/mod/05_standard/set/type/signup.rb +0 -2
- data/mod/05_standard/set/type/uri.rb +11 -0
- data/mod/05_standard/spec/set/all/rich_html_spec.rb +6 -6
- data/mod/05_standard/spec/set/all/rss_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/signup_spec.rb +0 -1
- data/mod/05_standard/spec/set/type/uri_spec.rb +41 -0
- data/public/assets/ace/mode-coffee.js +1 -0
- data/public/assets/ace/mode-css.js +1 -0
- data/public/assets/ace/mode-html.js +1 -0
- data/public/assets/ace/mode-javascript.js +1 -0
- data/public/assets/ace/mode-json.js +1 -0
- data/public/assets/ace/mode-scss.js +922 -0
- data/public/assets/ace/theme-github.js +98 -0
- data/public/assets/ace/theme-textmate.js +1 -0
- data/public/assets/ace/worker-coffee.js +1 -0
- data/public/assets/ace/worker-css.js +1 -0
- data/public/assets/ace/worker-html.js +1 -0
- data/public/assets/ace/worker-javascript.js +1 -0
- data/public/assets/ace/worker-json.js +1 -0
- data/spec/controllers/card_controller_spec.rb +0 -1
- data/spec/controllers/location_spec.rb +0 -2
- data/spec/javascripts/helpers/jasmine-jquery.js +812 -0
- data/spec/javascripts/support/jasmine.yml +8 -6
- data/spec/javascripts/support/jasmine_config.rb +1 -1
- data/spec/javascripts/support/jasmine_runner.rb +1 -1
- data/spec/javascripts/wagn_spec.coffee +2 -0
- data/spec/lib/card/content_spec.rb +28 -6
- data/spec/lib/card/format_spec.rb +62 -15
- data/spec/lib/card/reference_spec.rb +3 -3
- data/spec/spec_helper.rb +2 -2
- data/test/fixtures/card_actions.yml +1260 -1239
- data/test/fixtures/card_acts.yml +347 -341
- data/test/fixtures/card_changes.yml +2345 -2276
- data/test/fixtures/card_references.yml +4098 -1606
- data/test/fixtures/cards.yml +1950 -1887
- metadata +39 -13
- data/lib/card/query/ref_spec.rb +0 -37
- data/lib/card/query/value_spec.rb +0 -65
- data/lib/wagn/location.rb +0 -93
- data/spec/javascripts/helpers/jasmine-config.js +0 -2
- data/spec/javascripts/helpers/jasmine-jquery-1.3.1.js +0 -295
@@ -0,0 +1,145 @@
|
|
1
|
+
format :html do
|
2
|
+
###---( TOP_LEVEL (used by menu) NEW / EDIT VIEWS )
|
3
|
+
|
4
|
+
view :new, :perms=>:create, :tags=>:unknown_ok do |args|
|
5
|
+
frame_and_form :create, args, 'main-success'=>'REDIRECT' do
|
6
|
+
[
|
7
|
+
_optional_render( :name_fieldset, args ),
|
8
|
+
_optional_render( :type_fieldset, args ),
|
9
|
+
_optional_render( :content_fieldsets, args ),
|
10
|
+
_optional_render( :button_fieldset, args )
|
11
|
+
]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def default_new_args args
|
17
|
+
hidden = args[:hidden] ||= {}
|
18
|
+
hidden[:success] ||= card.rule(:thanks) || '_self'
|
19
|
+
hidden[:card ] ||={}
|
20
|
+
|
21
|
+
args[:optional_help] ||= :show
|
22
|
+
|
23
|
+
# name field / title
|
24
|
+
if !params[:name_prompt] and !card.cardname.blank?
|
25
|
+
# name is ready and will show up in title
|
26
|
+
hidden[:card][:name] ||= card.name
|
27
|
+
else
|
28
|
+
# name is not ready; need generic title
|
29
|
+
args[:title] ||= "New #{ card.type_name unless card.type_id == Card.default_type_id }" #fixme - overrides nest args
|
30
|
+
unless card.rule_card :autoname
|
31
|
+
# prompt for name
|
32
|
+
hidden[:name_prompt] = true unless hidden.has_key? :name_prompt
|
33
|
+
args[:optional_name_fieldset] ||= :show
|
34
|
+
end
|
35
|
+
end
|
36
|
+
args[:optional_name_fieldset] ||= :hide
|
37
|
+
|
38
|
+
|
39
|
+
# type field
|
40
|
+
if ( !params[:type] and !args[:type] and
|
41
|
+
( main? || card.simple? || card.is_template? ) and
|
42
|
+
Card.new( :type_id=>card.type_id ).ok? :create #otherwise current type won't be on menu
|
43
|
+
)
|
44
|
+
args[:optional_type_fieldset] = :show
|
45
|
+
else
|
46
|
+
hidden[:card][:type_id] ||= card.type_id
|
47
|
+
args[:optional_type_fieldset] = :hide
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
cancel = if main?
|
52
|
+
{ :class=>'redirecter', :href=>Card.path_setting('/*previous') }
|
53
|
+
else
|
54
|
+
{ :class=>'slotter', :href=>path( :view=>:missing ) }
|
55
|
+
end
|
56
|
+
|
57
|
+
args[:buttons] ||= %{
|
58
|
+
#{ button_tag 'Submit', :class=>'create-submit-button', :disable_with=>'Submitting' }
|
59
|
+
#{ button_tag 'Cancel', :type=>'button', :class=>"create-cancel-button #{cancel[:class]}", :href=>cancel[:href] }
|
60
|
+
}
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
view :edit, :perms=>:update, :tags=>:unknown_ok do |args|
|
66
|
+
frame_and_form :update, args do
|
67
|
+
[
|
68
|
+
_optional_render( :content_fieldsets, args ),
|
69
|
+
_optional_render( :button_fieldset, args )
|
70
|
+
]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def default_edit_args args
|
75
|
+
args[:optional_help] = :show
|
76
|
+
|
77
|
+
args[:buttons] = %{
|
78
|
+
#{ button_tag 'Submit', :class=>'submit-button', :disable_with=>'Submitting' }
|
79
|
+
#{ button_tag 'Cancel', :class=>'cancel-button slotter', :href=>path, :type=>'button' }
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
view :edit_name, :perms=>:update do |args|
|
84
|
+
frame_and_form( { :action=>:update, :id=>card.id }, args, 'main-success'=>'REDIRECT' ) do
|
85
|
+
[
|
86
|
+
_render_name_fieldset( args ),
|
87
|
+
_optional_render( :confirm_rename, args ),
|
88
|
+
_optional_render( :button_fieldset, args )
|
89
|
+
]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
view :confirm_rename do |args|
|
94
|
+
referers = args[:referers]
|
95
|
+
dependents = card.dependents
|
96
|
+
wrap args do
|
97
|
+
%{
|
98
|
+
<h1>Are you sure you want to rename <em>#{card.name}</em>?</h1>
|
99
|
+
#{ %{ <h2>This change will...</h2> } if referers.any? || dependents.any? }
|
100
|
+
<ul>
|
101
|
+
#{ %{<li>automatically alter #{ dependents.size } related name(s). } if dependents.any? }
|
102
|
+
#{ %{<li>affect at least #{referers.size} reference(s) to "#{card.name}".} if referers.any? }
|
103
|
+
</ul>
|
104
|
+
#{ %{<p>You may choose to <em>update or ignore</em> the references.</p>} if referers.any? }
|
105
|
+
}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def default_edit_name_args args
|
110
|
+
referers = args[:referers] = card.extended_referencers
|
111
|
+
args[:hidden] ||= {}
|
112
|
+
args[:hidden].reverse_merge!(
|
113
|
+
:success => '_self',
|
114
|
+
:old_name => card.name,
|
115
|
+
:referers => referers.size,
|
116
|
+
:card => { :update_referencers => false }
|
117
|
+
)
|
118
|
+
args[:buttons] = %{
|
119
|
+
#{ button_tag 'Rename and Update', :disable_with=>'Renaming', :class=>'renamer-updater' }
|
120
|
+
#{ button_tag 'Rename', :disable_with=>'Renaming', :class=>'renamer' }
|
121
|
+
#{ button_tag 'Cancel', :class=>'slotter', :type=>'button', :href=>path(:view=>:edit, :id=>card.id)}
|
122
|
+
}
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
view :edit_type, :perms=>:update do |args|
|
128
|
+
frame_and_form :update, args do
|
129
|
+
#'main-success'=>'REDIRECT: _self', # adding this back in would make main cards redirect on cardtype changes
|
130
|
+
[
|
131
|
+
_render_type_fieldset( args ),
|
132
|
+
optional_render( :button_fieldset, args )
|
133
|
+
]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def default_edit_type_args args
|
138
|
+
args[:variety] = :edit #YUCK!
|
139
|
+
args[:hidden] ||= { :view=>:edit }
|
140
|
+
args[:buttons] = %{
|
141
|
+
#{ button_tag 'Submit', :disable_with=>'Submitting' }
|
142
|
+
#{ button_tag 'Cancel', :href=>path(:view=>:edit), :type=>'button', :class=>'slotter' }
|
143
|
+
}
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
format do
|
2
|
+
view :closed_missing, :perms=>:none do |args| '' end
|
3
|
+
view :missing, :perms=>:none do |args| '' end
|
4
|
+
|
5
|
+
view :not_found, :perms=>:none, :error_code=>404 do |args|
|
6
|
+
%{ Could not find #{card.name.present? ? %{"#{card.name}"} : 'the card requested'}. }
|
7
|
+
end
|
8
|
+
|
9
|
+
view :server_error, :perms=>:none, :error_code=>500 do |args|
|
10
|
+
%{ Wagn Hitch! Server Error. Yuck, sorry about that.\n}+
|
11
|
+
%{ To tell us more and follow the fix, add a support ticket at http://wagn.org/new/Support_Ticket }
|
12
|
+
end
|
13
|
+
|
14
|
+
view :denial, :perms=>:none, :error_code=>403 do |args|
|
15
|
+
focal? ? 'Permission Denied' : ''
|
16
|
+
end
|
17
|
+
|
18
|
+
view :bad_address, :perms=>:none, :error_code=>404 do |args|
|
19
|
+
%{ 404: Bad Address }
|
20
|
+
end
|
21
|
+
|
22
|
+
view :too_deep, :perms=>:none do |args|
|
23
|
+
%{ Man, you're too deep. (Too many levels of inclusions at a time) }
|
24
|
+
end
|
25
|
+
|
26
|
+
view :too_slow, :perms=>:none do |args|
|
27
|
+
%{ Timed out! #{ showname } took too long to load. }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
format :html do
|
33
|
+
def view_for_unknown view, args
|
34
|
+
case
|
35
|
+
when focal? && ok?( :create ) ; :new
|
36
|
+
when commentable?( view, args ) ; view
|
37
|
+
else super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def commentable? view, args
|
42
|
+
self.class.tagged view, :comment and
|
43
|
+
show_view? :comment_box, args.merge( :default_visibility=>:hide ) and #developer or wagneer has overridden default
|
44
|
+
ok? :comment
|
45
|
+
end
|
46
|
+
|
47
|
+
def rendering_error exception, view
|
48
|
+
%{
|
49
|
+
|
50
|
+
<span class="render-error">
|
51
|
+
error rendering
|
52
|
+
#{
|
53
|
+
if Auth.always_ok?
|
54
|
+
%{
|
55
|
+
#{ card_link error_cardname, :class=>'render-error-link' }
|
56
|
+
<div class="render-error-message errors-view" style="display:none">
|
57
|
+
<h3>Error message (visible to admin only)</h3>
|
58
|
+
<p><strong>#{ exception.message }</strong></p>
|
59
|
+
<div>
|
60
|
+
#{exception.backtrace * "<br>\n"}
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
}
|
64
|
+
else
|
65
|
+
error_cardname
|
66
|
+
end
|
67
|
+
}
|
68
|
+
(#{view} view)
|
69
|
+
</span>
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def unsupported_view view
|
74
|
+
"<strong>view <em>#{view}</em> not supported for <em>#{error_cardname}</em></strong>"
|
75
|
+
end
|
76
|
+
|
77
|
+
view :message, :perms=>:none, :tags=>:unknown_ok do |args|
|
78
|
+
frame args do
|
79
|
+
params[:message]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
view :missing do |args|
|
85
|
+
return '' unless card.ok? :create # should this be moved into ok_view?
|
86
|
+
|
87
|
+
opts = { :remote=>true, :class=>"slotter missing-#{ args[:denied_view] || args[:home_view]}" }
|
88
|
+
|
89
|
+
wrap args do
|
90
|
+
view_link "Add #{ fancy_title args[:title] }", :new, opts
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
view :closed_missing, :perms=>:none do |args|
|
95
|
+
%{<span class="faint"> #{ showname } </span>}
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
view :conflict, :error_code=>409 do |args|
|
101
|
+
# FIXME: hack to get the conflicted update as a proper act for the diff view
|
102
|
+
card.current_act.save
|
103
|
+
action = card.actions.last # the unsaved action with the new changes
|
104
|
+
action.card_act_id = card.current_act.id
|
105
|
+
action.draft = true
|
106
|
+
action.save
|
107
|
+
card.store_changes # deletes action if there are no changes
|
108
|
+
|
109
|
+
# as a consequence card.current_act.actions can be empty when both users made exactly the same changes
|
110
|
+
# but an act is always supposed to have at least one action, so we have to delete the act to avoid bad things
|
111
|
+
card.current_act.reload
|
112
|
+
if card.current_act.actions.empty?
|
113
|
+
card.current_act.delete
|
114
|
+
card.current_act = nil
|
115
|
+
end
|
116
|
+
|
117
|
+
wrap args.merge( :slot_class=>'error-view' ) do #ENGLISH below
|
118
|
+
%{<strong>Conflict!</strong><span class="new-current-revision-id">#{card.last_action_id}</span>
|
119
|
+
<div>#{ card_link card.last_action.act.actor.cardname } has also been making changes.</div>
|
120
|
+
<div>Please examine below, resolve above, and re-submit.</div>
|
121
|
+
#{ wrap do |args|
|
122
|
+
if card.current_act
|
123
|
+
_render_act_expanded :act=>card.current_act, :current_rev_nr => 0
|
124
|
+
else
|
125
|
+
"No difference between your changes and #{card.last_action.act.actor.name}'s version."
|
126
|
+
end
|
127
|
+
end
|
128
|
+
}
|
129
|
+
}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
view :errors, :perms=>:none do |args|
|
134
|
+
if card.errors.any?
|
135
|
+
title = %{ Problems #{%{ with #{card.name} } unless card.name.blank?} }
|
136
|
+
frame args.merge( :title=>title ) do
|
137
|
+
card.errors.map do |attrib, msg|
|
138
|
+
msg = "#{attrib.to_s.upcase}: #{msg}" unless attrib == :abort
|
139
|
+
%{ <div class="card-error-msg">#{msg}</div> }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
view :not_found do |args| #ug. bad name.
|
146
|
+
sign_in_or_up_links = if !Auth.signed_in?
|
147
|
+
%{<div>
|
148
|
+
#{ card_link ':signin', :text=>'Sign in' } or
|
149
|
+
#{ link_to 'Sign up', wagn_path('new/:signup') } to create it.
|
150
|
+
</div>}
|
151
|
+
end
|
152
|
+
frame args.merge(:title=>'Not Found', :optional_menu=>:never) do
|
153
|
+
%{
|
154
|
+
<h2>Could not find #{card.name.present? ? "<em>#{card.name}</em>" : 'that'}.</h2>
|
155
|
+
#{sign_in_or_up_links}
|
156
|
+
}
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
view :denial do |args|
|
161
|
+
to_task = if task = args[:denied_task]
|
162
|
+
%{to #{task} this.}
|
163
|
+
else
|
164
|
+
'to do that.'
|
165
|
+
end
|
166
|
+
|
167
|
+
if !focal?
|
168
|
+
%{<span class="denied"><!-- Sorry, you don't have permission #{to_task} --></span>}
|
169
|
+
else
|
170
|
+
frame args do #ENGLISH below
|
171
|
+
message = case
|
172
|
+
when task != :read && Wagn.config.read_only
|
173
|
+
"We are currently in read-only mode. Please try again later."
|
174
|
+
when Auth.signed_in?
|
175
|
+
"You need permission #{to_task}"
|
176
|
+
else
|
177
|
+
or_signup = if Card.new(:type_id=>Card::SignupID).ok? :create
|
178
|
+
"or #{ link_to 'sign up', wagn_url('new/:signup') }"
|
179
|
+
end
|
180
|
+
save_interrupted_action(request.env['REQUEST_URI'])
|
181
|
+
"You have to #{ link_to 'sign in', wagn_url(':signin') } #{or_signup} #{to_task}"
|
182
|
+
end
|
183
|
+
|
184
|
+
%{<h1>Sorry!</h1>\n<div>#{ message }</div>}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
view :server_error do |args|
|
191
|
+
%{
|
192
|
+
<body>
|
193
|
+
<div class="dialog">
|
194
|
+
<h1>Wagn Hitch :(</h1>
|
195
|
+
<p>Server Error. Yuck, sorry about that.</p>
|
196
|
+
<p><a href="http://www.wagn.org/new/Support_Ticket">Add a support ticket</a>
|
197
|
+
to tell us more and follow the fix.</p>
|
198
|
+
</div>
|
199
|
+
</body>
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
@@ -29,14 +29,14 @@ format :html do
|
|
29
29
|
return '' unless watched_card
|
30
30
|
|
31
31
|
following = Auth.current.fetch :trait=>:following, :new=>{:type=>:pointer}
|
32
|
-
path_hash = {:
|
32
|
+
path_hash = {:name=>following.name, :action=>:update, :toggle=>toggle,
|
33
33
|
:success=>{:id=>card.name, :view=>:watch} }
|
34
34
|
case toggle
|
35
35
|
when :off then path_hash[:drop_item] = watched_card.cardname.url_key
|
36
36
|
when :on then path_hash[:add_item] = watched_card.cardname.url_key
|
37
37
|
end
|
38
38
|
|
39
|
-
link_to "#{text}",
|
39
|
+
link_to "#{text}", path_hash,
|
40
40
|
{:class=>"watch-toggle watch-toggle-#{toggle} slotter", :title=>title, :remote=>true, :method=>'post'}.merge(extra)
|
41
41
|
end
|
42
42
|
|
@@ -0,0 +1,211 @@
|
|
1
|
+
format :html do
|
2
|
+
def edit_slot args={}
|
3
|
+
#note: @mode should already be :edit here...
|
4
|
+
if args[:structure] || card.structure
|
5
|
+
# multi-card editing
|
6
|
+
|
7
|
+
if args[:core_edit] #need better name!
|
8
|
+
_render_core args
|
9
|
+
else
|
10
|
+
process_relative_tags args
|
11
|
+
end
|
12
|
+
|
13
|
+
else
|
14
|
+
# single-card edit mode
|
15
|
+
field = content_field form, args
|
16
|
+
|
17
|
+
if [ args[:optional_type_fieldset], args[:optional_name_fieldset] ].member? :show
|
18
|
+
# display content field in fieldset for consistency with other fields
|
19
|
+
fieldset '', field, :editor=>:content
|
20
|
+
else
|
21
|
+
editor_wrap( :content ) { field }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def form_for_multi
|
28
|
+
block = Proc.new {}
|
29
|
+
builder = ActionView::Base.default_form_builder
|
30
|
+
card.name = card.name.gsub(/^#{Regexp.escape(root.card.name)}\+/, '+') if root.card.new_card? ##FIXME -- need to match other relative inclusions.
|
31
|
+
|
32
|
+
builder.new("card[subcards][#{card.relative_name}]", card, template, {}, block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def form
|
36
|
+
@form ||= form_for_multi
|
37
|
+
end
|
38
|
+
|
39
|
+
def card_form action, opts={}
|
40
|
+
hidden_args = opts.delete :hidden
|
41
|
+
form_for card, card_form_opts(action, opts) do |form|
|
42
|
+
@form = form
|
43
|
+
%{
|
44
|
+
#{ hidden_tags hidden_args if hidden_args }
|
45
|
+
#{ yield form }
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def card_form_opts action, html={}
|
51
|
+
url, action = case action
|
52
|
+
when Symbol ; [ path(:action=>action) , action ]
|
53
|
+
when Hash ; [ path(action) , action[:action] ]
|
54
|
+
when String ; [ wagn_path(action) , nil ] #deprecated
|
55
|
+
else ; raise Card::Error, "unsupported card_form action class: #{action.class}"
|
56
|
+
end
|
57
|
+
|
58
|
+
klasses = Array.wrap( html[:class] )
|
59
|
+
klasses << 'card-form slotter'
|
60
|
+
klasses << 'autosave' if action == :update
|
61
|
+
html[:class] = klasses.join ' '
|
62
|
+
|
63
|
+
html[:recaptcha] ||= 'on' if card.recaptcha_on?
|
64
|
+
html.delete :recaptcha if html[:recaptcha] == :off
|
65
|
+
|
66
|
+
{ :url=>url, :remote=>true, :html=>html }
|
67
|
+
end
|
68
|
+
|
69
|
+
def editor_wrap type=nil
|
70
|
+
content_tag( :div, :class=>"editor#{ " #{type}-editor" if type }" ) { yield }
|
71
|
+
end
|
72
|
+
|
73
|
+
def fieldset title, content, opts={}
|
74
|
+
if attribs = opts[:attribs]
|
75
|
+
attrib_string = attribs.keys.map do |key|
|
76
|
+
%{#{key}="#{attribs[key]}"}
|
77
|
+
end * ' '
|
78
|
+
end
|
79
|
+
help_text = case opts[:help]
|
80
|
+
when String ; _render_help :help_text=> opts[:help]
|
81
|
+
when true ; _render_help
|
82
|
+
else ; nil
|
83
|
+
end
|
84
|
+
%{
|
85
|
+
<fieldset #{ attrib_string }>
|
86
|
+
<legend>
|
87
|
+
<h2>#{ title }</h2>
|
88
|
+
#{ help_text }
|
89
|
+
</legend>
|
90
|
+
#{ editor_wrap( opts[:editor] ) { content } }
|
91
|
+
</fieldset>
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def hidden_tags hash, base=nil
|
96
|
+
# convert hash into a collection of hidden tags
|
97
|
+
result = ''
|
98
|
+
hash ||= {}
|
99
|
+
hash.each do |key, val|
|
100
|
+
result += if Hash === val
|
101
|
+
hidden_tags val, key
|
102
|
+
else
|
103
|
+
name = base ? "#{base}[#{key}]" : key
|
104
|
+
hidden_field_tag name, val
|
105
|
+
end
|
106
|
+
end
|
107
|
+
result
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# FIELDSET VIEWS
|
112
|
+
|
113
|
+
view :name_fieldset do |args|
|
114
|
+
fieldset 'name', raw( name_field form ), :editor=>'name', :help=>args[:help]
|
115
|
+
end
|
116
|
+
|
117
|
+
view :type_fieldset do |args|
|
118
|
+
field = if args[:variety] == :edit #FIXME dislike this api -ef
|
119
|
+
type_field :class=>'type-field edit-type-field'
|
120
|
+
else
|
121
|
+
type_field :class=>"type-field live-type-field", :href=>path(:view=>:new), 'data-remote'=>true
|
122
|
+
end
|
123
|
+
fieldset 'type', field, :editor => 'type', :attribs => { :class=>'type-fieldset'}
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
view :button_fieldset do |args|
|
128
|
+
%{
|
129
|
+
<fieldset>
|
130
|
+
<div class="button-area">
|
131
|
+
#{ args[:buttons] }
|
132
|
+
</div>
|
133
|
+
</fieldset>
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
view :content_fieldsets do |args|
|
138
|
+
raw %{
|
139
|
+
<div class="card-editor editor">
|
140
|
+
#{ edit_slot args }
|
141
|
+
</div>
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
def name_field form=nil, options={}
|
147
|
+
form ||= self.form
|
148
|
+
form.text_field( :name, {
|
149
|
+
:value=>card.name, #needed because otherwise gets wrong value if there are updates
|
150
|
+
:autocomplete=>'off'
|
151
|
+
}.merge(options))
|
152
|
+
end
|
153
|
+
|
154
|
+
def type_field args={}
|
155
|
+
typelist = Auth.createable_types
|
156
|
+
current_type = unless args.delete :no_current_type
|
157
|
+
unless card.new_card? || typelist.include?( card.type_name )
|
158
|
+
# current type should be an option on existing cards, regardless of create perms
|
159
|
+
typelist = (typelist << card.type_name).sort
|
160
|
+
end
|
161
|
+
Card[ card ? card.type_id : Card.default_type_id ].name
|
162
|
+
end
|
163
|
+
|
164
|
+
options = options_from_collection_for_select typelist, :to_s, :to_s, current_type
|
165
|
+
template.select_tag 'card[type]', options, args
|
166
|
+
end
|
167
|
+
|
168
|
+
def content_field form, options={}
|
169
|
+
@form = form
|
170
|
+
@nested = options[:nested]
|
171
|
+
card.last_action_id_before_edit = card.last_action_id
|
172
|
+
revision_tracking = if card && !card.new_card? && !options[:skip_rev_id]
|
173
|
+
form.hidden_field :last_action_id_before_edit, :class=>'current_revision_id'
|
174
|
+
#hidden_field_tag 'card[last_action_id_before_edit]', card.last_action_id, :class=>'current_revision_id'
|
175
|
+
end
|
176
|
+
%{
|
177
|
+
#{ revision_tracking
|
178
|
+
}
|
179
|
+
#{ _render_editor options }
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
# FIELD VIEWS
|
185
|
+
|
186
|
+
view :editor do |args|
|
187
|
+
form.text_area :content, :rows=>3, :class=>'tinymce-textarea card-content', :id=>unique_id
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
view :edit_in_form, :perms=>:update, :tags=>:unknown_ok do |args|
|
192
|
+
eform = form_for_multi
|
193
|
+
content = content_field eform, args.merge( :nested=>true )
|
194
|
+
opts = { :editor=>'content', :help=>true, :attribs =>
|
195
|
+
{ :class=> "card-editor RIGHT-#{ card.cardname.tag_name.safe_key }" }
|
196
|
+
}
|
197
|
+
if card.new_card?
|
198
|
+
content += raw( "\n #{ eform.hidden_field :type_id }" )
|
199
|
+
else
|
200
|
+
opts[:attribs].merge! :card_id=>card.id, :card_name=>(h card.name)
|
201
|
+
end
|
202
|
+
|
203
|
+
fieldset fancy_title( args[:title] ), content, opts
|
204
|
+
end
|
205
|
+
|
206
|
+
def process_relative_tags args
|
207
|
+
_render_raw(args).scan( /\{\{\s*\+[^\}]*\}\}/ ).map do |inc| #fixme - wrong place for regexp!
|
208
|
+
process_content( inc ).strip
|
209
|
+
end.join
|
210
|
+
end
|
211
|
+
end
|