radiant-concurrent_draft-extension 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HELP.rdoc +32 -0
- data/README.textile +52 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/app/views/admin/_draft_controls.html.haml +85 -0
- data/app/views/admin/_edit_buttons.html.haml +10 -0
- data/app/views/admin/layouts/_edit_content.html.haml +5 -0
- data/app/views/admin/page_parts/_page_part.html.haml +20 -0
- data/app/views/admin/pages/_edit_layout_and_type.html.haml +11 -0
- data/app/views/admin/pages/_published_meta.html.haml +4 -0
- data/app/views/admin/snippets/_edit_content.html.haml +5 -0
- data/app/views/admin/users/_edit_roles.html.haml +26 -0
- data/concurrent_draft_extension.rb +30 -0
- data/config/initializers/radiant_config.rb +3 -0
- data/config/locales/en.yml +11 -0
- data/config/routes.rb +9 -0
- data/db/migrate/001_update_schemata.rb +29 -0
- data/db/migrate/002_create_draft_page_elements.rb +10 -0
- data/db/migrate/003_add_publisher_role.rb +9 -0
- data/lib/concurrent_draft/admin_controller_extensions.rb +52 -0
- data/lib/concurrent_draft/helper_extensions.rb +39 -0
- data/lib/concurrent_draft/model_extensions.rb +77 -0
- data/lib/concurrent_draft/page_extensions.rb +28 -0
- data/lib/concurrent_draft/site_controller_extensions.rb +16 -0
- data/lib/concurrent_draft/tags.rb +56 -0
- data/lib/tasks/concurrent_draft_extension_tasks.rake +46 -0
- data/public/images/admin/cancel.png +0 -0
- data/public/images/admin/clock.png +0 -0
- data/public/images/admin/page_delete.png +0 -0
- data/public/images/admin/page_edit.png +0 -0
- data/public/images/admin/page_refresh.png +0 -0
- data/public/images/admin/tick.png +0 -0
- data/public/javascripts/admin/concurrent_draft.js +72 -0
- data/public/stylesheets/admin/concurrent_draft.css +74 -0
- data/spec/controllers/admin_controller_extensions_spec.rb +184 -0
- data/spec/controllers/site_controller_extensions_spec.rb +31 -0
- data/spec/matchers/concurrent_draft_matcher.rb +11 -0
- data/spec/models/model_extensions_spec.rb +114 -0
- data/spec/models/page_extensions_spec.rb +56 -0
- data/spec/models/tags_spec.rb +43 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +38 -0
- data/test/helpers/caching_test_helper.rb +42 -0
- data/test/helpers/page_part_test_helper.rb +49 -0
- data/test/helpers/page_test_helper.rb +77 -0
- data/vendor/plugins/12_hour_time/CHANGELOG +2 -0
- data/vendor/plugins/12_hour_time/README +16 -0
- data/vendor/plugins/12_hour_time/Rakefile +22 -0
- data/vendor/plugins/12_hour_time/init.rb +1 -0
- data/vendor/plugins/12_hour_time/lib/12_hour_time.rb +78 -0
- data/vendor/plugins/12_hour_time/test/12_hour_time_test.rb +52 -0
- data/vendor/plugins/12_hour_time/test/test_helper.rb +3 -0
- metadata +143 -0
data/config/routes.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
map.page_schedule_draft_promotion 'admin/pages/schedule_draft_promotion/:id',
|
3
|
+
:controller => 'admin/pages', :action => 'schedule_draft_promotion'
|
4
|
+
map.snippet_schedule_draft_promotion 'admin/snippet/schedule_draft_promotion/:id',
|
5
|
+
:controller => 'admin/snippets', :action => 'schedule_draft_promotion'
|
6
|
+
map.layout_schedule_draft_promotion 'admin/layout/schedule_draft_promotion/:id',
|
7
|
+
:controller => 'admin/layouts', :action => 'schedule_draft_promotion'
|
8
|
+
map.page_unpublish 'admin/pages/unpublish/:id', :controller => 'admin/pages', :action => 'unpublish'
|
9
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class UpdateSchemata < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :pages, :draft_promotion_scheduled_at, :datetime
|
4
|
+
add_column :pages, :draft_promoted_at, :datetime
|
5
|
+
add_column :page_parts, :draft_content, :text
|
6
|
+
add_column :snippets, :draft_promotion_scheduled_at, :datetime
|
7
|
+
add_column :snippets, :draft_promoted_at, :datetime
|
8
|
+
add_column :snippets, :draft_content, :text
|
9
|
+
add_column :layouts, :draft_promotion_scheduled_at, :datetime
|
10
|
+
add_column :layouts, :draft_promoted_at, :datetime
|
11
|
+
add_column :layouts, :draft_content, :text
|
12
|
+
Page.reset_column_information
|
13
|
+
PagePart.reset_column_information
|
14
|
+
Snippet.reset_column_information
|
15
|
+
Layout.reset_column_information
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
remove_column :page_parts, :draft_content
|
20
|
+
remove_column :pages, :draft_promotion_scheduled_at
|
21
|
+
remove_column :pages,:draft_promoted_at
|
22
|
+
remove_column :snippets, :draft_content
|
23
|
+
remove_column :snippets, :draft_promotion_scheduled_at
|
24
|
+
remove_column :snippets, :draft_promoted_at
|
25
|
+
remove_column :layouts, :draft_content
|
26
|
+
remove_column :layouts, :draft_promotion_scheduled_at
|
27
|
+
remove_column :layouts, :draft_promoted_at
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ConcurrentDraft::AdminControllerExtensions
|
2
|
+
def self.included(base)
|
3
|
+
base.class_eval do
|
4
|
+
helper_method :model
|
5
|
+
helper_method :model_class
|
6
|
+
public :model, :model_class
|
7
|
+
only_allow_access_to :schedule_draft_promotion, :unpublish,
|
8
|
+
:when => [:publisher, :admin],
|
9
|
+
:denied_message => "You must have publisher privileges to execute this action.",
|
10
|
+
:denied_url => {:action => 'edit'}
|
11
|
+
after_filter :check_for_promote_now, :only => [:create, :update]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def authorized_user?
|
16
|
+
(current_user.publisher? || current_user.admin?)
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_for_promote_now
|
20
|
+
if params[:promote] && authorized_user?
|
21
|
+
model.promote_draft!
|
22
|
+
flash[:notice] = "The existing draft #{model_class.to_s.downcase} has been saved and promoted, and is now live."
|
23
|
+
flash.keep
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def schedule_draft_promotion
|
28
|
+
self.model = model_class.find(params[:id])
|
29
|
+
case params[:commit]
|
30
|
+
when model_class.promote_now_text
|
31
|
+
model.promote_draft!
|
32
|
+
flash[:notice] = "The existing draft #{model_class.to_s.downcase} has been promoted and is now live."
|
33
|
+
when model_class.schedule_promotion_text
|
34
|
+
if model.update_attributes(params[model.class.name.underscore.intern])
|
35
|
+
flash[:notice] = "The draft #{model_class.to_s.downcase} will be promoted on #{model.draft_promotion_scheduled_at.to_s(:long_civilian)}."
|
36
|
+
else
|
37
|
+
flash[:error] = model.errors.full_messages.to_sentence
|
38
|
+
end
|
39
|
+
when model_class.cancel_promotion_text
|
40
|
+
model.cancel_promotion!
|
41
|
+
flash[:notice] = "The scheduled draft #{model_class.to_s.downcase} promotion has been cancelled."
|
42
|
+
end
|
43
|
+
redirect_to :action => "edit"
|
44
|
+
end
|
45
|
+
|
46
|
+
def unpublish
|
47
|
+
self.model = model_class.find(params[:id])
|
48
|
+
model.unpublish!
|
49
|
+
flash[:notice] = "#{model_class} has been unpublished and reset to draft mode -- no draft promotion scheduled."
|
50
|
+
redirect_to :action => "edit"
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ConcurrentDraft::HelperExtensions
|
2
|
+
def updated_stamp(model)
|
3
|
+
unless model.new_record?
|
4
|
+
updated_by = (model.updated_by || model.created_by) if model.respond_to?(:updated_by)
|
5
|
+
login = updated_by ? updated_by.login : nil
|
6
|
+
time = (model.updated_at || model.created_at)
|
7
|
+
promoted_at = model.draft_promoted_at if model.respond_to?(:draft_promoted_at)
|
8
|
+
html = %{<p style="clear: left"><small>}
|
9
|
+
if login or time
|
10
|
+
html << 'Last updated '
|
11
|
+
html << %{by #{login} } if login
|
12
|
+
html << %{at #{ timestamp(time) }} if time
|
13
|
+
html << '. '
|
14
|
+
end
|
15
|
+
if promoted_at
|
16
|
+
html << %{Last promoted at #{ timestamp(promoted_at) }.}
|
17
|
+
end
|
18
|
+
html << %{</small></p>}
|
19
|
+
html
|
20
|
+
else
|
21
|
+
%{<p class="clear"> </p>}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_model_button(_model)
|
26
|
+
label = _model.new_record? ? "Create" : "Save"
|
27
|
+
submit_tag "#{label} and Exit", :class => 'button'
|
28
|
+
end
|
29
|
+
|
30
|
+
def save_model_and_continue_editing_button(_model)
|
31
|
+
label = _model.new_record? ? "Create" : "Save"
|
32
|
+
submit_tag label, :name => 'continue', :class => 'button'
|
33
|
+
end
|
34
|
+
|
35
|
+
def save_model_and_promote_button(_model)
|
36
|
+
label = _model.new_record? ? "Create" : "Save"
|
37
|
+
submit_tag "#{label} and Promote Now", :name => 'promote', :class => 'button'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ConcurrentDraft::ModelExtensions
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
base.class_eval do
|
6
|
+
validate :promotion_date_in_future
|
7
|
+
if instance_methods.include?('after_initialize')
|
8
|
+
alias_method_chain :after_initialize, :drafts
|
9
|
+
else
|
10
|
+
def after_initialize
|
11
|
+
promote_on_load
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def promote_now_text; "Promote Now" end
|
19
|
+
def schedule_promotion_text; "Schedule for promotion on -->" end
|
20
|
+
def cancel_promotion_text; "Cancel scheduled promotion" end
|
21
|
+
end
|
22
|
+
|
23
|
+
def display_name
|
24
|
+
if self.class.to_s == 'Page'
|
25
|
+
self.title
|
26
|
+
else
|
27
|
+
self.name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def promotion_date_in_future
|
32
|
+
if respond_to?(:draft_promotion_scheduled_at) && !draft_promotion_scheduled_at.blank? && draft_promotion_scheduled_at < Time.now
|
33
|
+
errors.add :draft_promotion_scheduled_at, "may not be in the past"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def promote_on_load
|
38
|
+
promote_draft! if respond_to?(:draft_promotion_scheduled_at) && draft_should_be_promoted?
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_initialize_with_drafts
|
42
|
+
promote_on_load
|
43
|
+
after_initialize_without_drafts
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_draft_promotion_scheduled?
|
47
|
+
!draft_promotion_scheduled_at.blank?
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_draft_promoted?
|
51
|
+
!draft_promoted_at.blank? && draft_promoted_at <= Time.now
|
52
|
+
end
|
53
|
+
|
54
|
+
def cancel_promotion!
|
55
|
+
update_attribute("draft_promotion_scheduled_at", nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
def draft_should_be_promoted?
|
59
|
+
has_draft_promotion_scheduled? && draft_promotion_scheduled_at <= Time.now
|
60
|
+
end
|
61
|
+
|
62
|
+
def promote_draft!
|
63
|
+
update_attributes("content" => draft_content) if respond_to?(:content) && respond_to?(:draft_content)
|
64
|
+
update_attributes("draft_promotion_scheduled_at" => nil, "draft_promoted_at" => Time.now) if respond_to?(:draft_promoted_at)
|
65
|
+
Radiant::Cache.clear if defined?(Radiant::Cache)
|
66
|
+
end
|
67
|
+
|
68
|
+
def unpublish!
|
69
|
+
update_attributes("content" => nil) if respond_to?(:content) && respond_to?(:draft_content)
|
70
|
+
update_attributes("draft_promotion_scheduled_at" => nil, "draft_promoted_at" => nil) if respond_to?(:draft_promoted_at)
|
71
|
+
end
|
72
|
+
|
73
|
+
def publishable?
|
74
|
+
has_attribute?("published_at") && has_attribute?("status_id")
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ConcurrentDraft::PageExtensions
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
alias_method_chain :parse_object, :drafts
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def promote_draft!
|
10
|
+
parts.reload.each(&:promote_draft!)
|
11
|
+
update_attribute('status_id', Status[:published].id)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def unpublish!
|
16
|
+
parts.each(&:unpublish!)
|
17
|
+
update_attributes('published_at' => nil, 'status_id' => Status[:draft].id)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parse_object_with_drafts(object)
|
24
|
+
object.content = object.draft_content unless published?
|
25
|
+
parse_object_without_drafts(object)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ConcurrentDraft::SiteControllerExtensions
|
2
|
+
def self.included(base)
|
3
|
+
base.class_eval do
|
4
|
+
before_filter :publish_if_scheduled, :only => :show_page
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def publish_if_scheduled
|
9
|
+
url = Array === params[:url] ? params[:url].join('/') : params[:url]
|
10
|
+
page = Page.find_by_url(url, false)
|
11
|
+
if page && !page.published? && page.draft_should_be_promoted?
|
12
|
+
page.update_attribute('status_id', Status[:published].id)
|
13
|
+
end
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ConcurrentDraft::Tags
|
2
|
+
include Radiant::Taggable
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
%w{content snippet}.each do |t|
|
7
|
+
alias_method "tag:old_#{t}", "tag:#{t}"
|
8
|
+
alias_method "tag:#{t}", "tag:concurrent_draft_#{t}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
tag 'concurrent_draft_content' do |tag|
|
14
|
+
page = tag.locals.page
|
15
|
+
part_name = tag_part_name(tag)
|
16
|
+
boolean_attr = proc do |attribute_name, default|
|
17
|
+
attribute = (tag.attr[attribute_name] || default).to_s
|
18
|
+
raise TagError.new(%{`#{attribute_name}' attribute of `content' tag must be set to either "true" or "false"}) unless attribute =~ /true|false/i
|
19
|
+
(attribute.downcase == 'true') ? true : false
|
20
|
+
end
|
21
|
+
inherit = boolean_attr['inherit', false]
|
22
|
+
part_page = page
|
23
|
+
if inherit
|
24
|
+
while (part_page.part(part_name).nil? and (not part_page.parent.nil?)) do
|
25
|
+
part_page = part_page.parent
|
26
|
+
end
|
27
|
+
end
|
28
|
+
contextual = boolean_attr['contextual', true]
|
29
|
+
part = part_page.part(part_name)
|
30
|
+
### CONCURRENT DRAFTS CHANGE ###
|
31
|
+
# Show the draft content on the dev site #
|
32
|
+
part.content = part.draft_content if part && dev?(tag.globals.page.request)
|
33
|
+
### END CONCURRENT DRAFTS CHANGE ###
|
34
|
+
tag.locals.page = part_page unless contextual
|
35
|
+
tag.globals.page.render_snippet(part) unless part.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
tag 'concurrent_draft_snippet' do |tag|
|
39
|
+
if name = tag.attr['name']
|
40
|
+
if snippet = Snippet.find_by_name(name.strip)
|
41
|
+
tag.locals.yield = tag.expand if tag.double?
|
42
|
+
### CONCURRENT DRAFTS CHANGE ###
|
43
|
+
# Show the draft content on the dev site #
|
44
|
+
# Promote the snippet if it needs to be #
|
45
|
+
snippet.promote_draft! if snippet.draft_should_be_promoted?
|
46
|
+
snippet.content = snippet.draft_content if dev?(tag.globals.page.request)
|
47
|
+
### END CONCURRENT DRAFTS CHANGE ###
|
48
|
+
tag.globals.page.render_snippet(snippet)
|
49
|
+
else
|
50
|
+
raise StandardTags::TagError.new("snippet not found: #{name}")
|
51
|
+
end
|
52
|
+
else
|
53
|
+
raise StandardTags::TagError.new("`snippet' tag must contain `name' attribute")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :concurrent_draft do
|
4
|
+
|
5
|
+
desc "Runs the migration of the ConcurrentDraft extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
ConcurrentDraftExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
else
|
11
|
+
ConcurrentDraftExtension.migrator.migrate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Copies public assets of the Concurrent Draft to the instance public/ directory."
|
16
|
+
task :update => :environment do
|
17
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
18
|
+
Dir[ConcurrentDraftExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
19
|
+
path = file.sub(ConcurrentDraftExtension.root, '')
|
20
|
+
directory = File.dirname(path)
|
21
|
+
puts "Copying #{path}..."
|
22
|
+
mkdir_p RAILS_ROOT + directory
|
23
|
+
cp file, RAILS_ROOT + path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Create drafts for all snippets"
|
28
|
+
task :create_draft_snippets => :environment do
|
29
|
+
print 'copying content to draft_content for all snippets...'
|
30
|
+
Snippet.update_all('draft_content = content')
|
31
|
+
puts 'done.'
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Promote all drafts of all assets"
|
35
|
+
task :promote_all => :environment do
|
36
|
+
[Page, Snippet, Layout].each do |asset|
|
37
|
+
print "Promoting all #{asset.to_s.pluralize}..."
|
38
|
+
@user = User.find(:first) ## Admin user
|
39
|
+
asset.find(:all).each(&:promote_draft!)
|
40
|
+
asset.update_all("updated_by_id = #{@user.id}")
|
41
|
+
puts "done."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Event.addBehavior({'a.popup': Popup.TriggerBehavior()});
|
2
|
+
|
3
|
+
var Draft = {};
|
4
|
+
|
5
|
+
Draft.ControlBox = Behavior.create({
|
6
|
+
initialize: function(){
|
7
|
+
document.observe('click', Element.removeClassName.curry(this.element, 'active'));
|
8
|
+
},
|
9
|
+
onclick: function(e){
|
10
|
+
e.stop();
|
11
|
+
this.element.addClassName('active');
|
12
|
+
}
|
13
|
+
});
|
14
|
+
|
15
|
+
Draft.RevertLink = Behavior.create({
|
16
|
+
initialize: function(){
|
17
|
+
this.popup = $('revert-draft-popup');
|
18
|
+
},
|
19
|
+
onclick: function(e){
|
20
|
+
e.stop();
|
21
|
+
this.element.up('.active').removeClassName('active');
|
22
|
+
$$('input[name*="[content]"]').each(this.copyData, this);
|
23
|
+
center(this.popup);
|
24
|
+
this.popup.show();
|
25
|
+
},
|
26
|
+
copyData: function(input){
|
27
|
+
// var draft_id = input.name.gsub(/content/, 'draft_content').gsub(/[\[\]]+/, '_').sub(/\_*$/, '');
|
28
|
+
var draft_id = input.id.gsub(/content/, 'draft_content');
|
29
|
+
var draft = $(draft_id);
|
30
|
+
// The following was modified to accommodate templates extension
|
31
|
+
if (draft) {
|
32
|
+
switch(draft.type){
|
33
|
+
case 'checkbox':
|
34
|
+
draft.checked = (input.value == draft.value);
|
35
|
+
break;
|
36
|
+
default:
|
37
|
+
draft.value = input.value;
|
38
|
+
break;
|
39
|
+
}
|
40
|
+
draft.fire('draft:reverted');
|
41
|
+
} else {
|
42
|
+
// for true/false radio buttons in templates extension
|
43
|
+
var draft_true = document.getElementById(draft_id + '_true');
|
44
|
+
var draft_false = document.getElementById(draft_id + '_false');
|
45
|
+
if (draft_true && draft_false && draft_true.type == 'radio' && draft_false.type == 'radio') {
|
46
|
+
if (input.value == 'true') {
|
47
|
+
draft_true.checked = true;
|
48
|
+
} else if (input.value == 'false') {
|
49
|
+
draft_false.checked = true;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
Draft.ScheduleLink = Behavior.create({
|
57
|
+
onclick: function(e){
|
58
|
+
e.stop();
|
59
|
+
this.element.up('.active').removeClassName('.active');
|
60
|
+
var element = $(this.element.href.split('#')[1]);
|
61
|
+
center(element);
|
62
|
+
element.show();
|
63
|
+
element.down('form').focus();
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
|
68
|
+
Event.addBehavior({
|
69
|
+
'#draft-controls': Draft.ControlBox,
|
70
|
+
'#draft-controls li.revert a': Draft.RevertLink,
|
71
|
+
'#draft-controls li.schedule_draft a': Draft.ScheduleLink
|
72
|
+
});
|