backlog 0.35.5 → 0.36.2
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/Gemfile +19 -0
- data/Gemfile~ +4 -0
- data/History.txt +25 -0
- data/Rakefile +3 -3
- data/app/controllers/{application.rb → application_controller.rb} +1 -2
- data/app/controllers/backlogs_controller.rb +0 -16
- data/app/controllers/search_controller.rb +0 -2
- data/app/controllers/user_controller.rb +7 -7
- data/app/controllers/work_locks_controller.rb +2 -2
- data/app/controllers/works_controller.rb +23 -23
- data/app/helpers/application_helper.rb +9 -6
- data/app/helpers/backlogs_helper.rb +1 -1
- data/app/helpers/periods_helper.rb +1 -1
- data/app/models/backlog.rb +13 -10
- data/app/models/period.rb +0 -5
- data/app/models/sidebar.rb +1 -0
- data/app/models/task.rb +4 -10
- data/app/models/user.rb +5 -6
- data/app/models/user_notify.rb +0 -1
- data/app/models/work.rb +20 -25
- data/app/models/works_report_filter.rb +4 -4
- data/app/views/backlogs/_buttons.rhtml +1 -1
- data/app/views/backlogs/_form.rhtml +5 -9
- data/app/views/layouts/_left_top.rhtml +0 -1
- data/app/views/periods/_form.rhtml +1 -1
- data/app/views/search/results.rhtml +1 -12
- data/app/views/task_notify/{invite_en.rhtml → invite.en.html.erb} +0 -0
- data/app/views/task_notify/{invite_no.rhtml → invite.no.html.erb} +0 -0
- data/app/views/tasks/_task.rhtml +49 -50
- data/app/views/tasks/edit.rhtml +4 -4
- data/app/views/tasks/start_work.rjs +1 -1
- data/app/views/user/_edit.rhtml +1 -1
- data/app/views/user/change_password.rhtml +1 -1
- data/app/views/user/edit.rhtml +4 -4
- data/app/views/user/signup.rhtml +2 -2
- data/app/views/user_notify/{change_password_en.rhtml → change_password.en.html.erb} +0 -0
- data/app/views/user_notify/{change_password_no.rhtml → change_password.no.html.erb} +0 -0
- data/app/views/user_notify/{forgot_password_en.rhtml → forgot_password.en.html.erb} +0 -0
- data/app/views/user_notify/{forgot_password_no.rhtml → forgot_password.no.html.erb} +0 -0
- data/app/views/user_notify/{monitoring_en.rhtml → monitoring.en.html.erb} +0 -0
- data/app/views/user_notify/{monitoring_no.rhtml → monitoring.no.html.erb} +0 -0
- data/app/views/user_notify/{monitoring_invitation_en.rhtml → monitoring_invitation.en.html.erb} +0 -0
- data/app/views/user_notify/{monitoring_invitation_no.rhtml → monitoring_invitation.no.html.erb} +0 -0
- data/app/views/user_notify/{signup_en.rhtml → signup.en.html.erb} +0 -0
- data/app/views/user_notify/{signup_no.rhtml → signup.no.html.erb} +0 -0
- data/app/views/work_lock_notify/{lock_en.rhtml → lock.en.html.erb} +0 -0
- data/app/views/work_lock_notify/{lock_no.rhtml → lock.no.html.erb} +0 -0
- data/app/views/work_lock_notify/{nag_en.rhtml → nag.en.html.erb} +0 -0
- data/app/views/work_lock_notify/{nag_no.rhtml → nag.no.html.erb} +0 -0
- data/app/views/works/_form.rhtml +6 -6
- data/app/views/works/_new_row.rhtml +6 -6
- data/app/views/works/_row.rhtml +2 -2
- data/app/views/works/daily_work_sheet.rhtml +1 -1
- data/app/views/works/list.rhtml +6 -6
- data/app/views/works/list_excel.rhtml +8 -4
- data/app/views/works/timeliste.rhtml +14 -14
- data/app/views/works/update_row.rjs +1 -1
- data/app/views/works/weekly_work_sheet.rhtml +5 -5
- data/app/views/works/weekly_work_sheet_details.rhtml +5 -5
- data/config/boot.rb +108 -27
- data/config/database.yml +3 -26
- data/config/environment.rb +4 -12
- data/config/environments/development.rb +0 -1
- data/config/initializers/jdbc.rb +7 -0
- data/config/initializers/mongrel.rb +83 -0
- data/config/locales/en.yml +189 -0
- data/config/locales/no.yml +192 -0
- data/config/preinitializer.rb +20 -0
- data/cruise_build.sh +10 -0
- data/cruise_config.rb +1 -1
- data/db/migrate/20100720124707_merge_work_account_into_backlog.rb +74 -0
- data/db/schema.rb +93 -127
- data/lib/class_table_inheritance.rb +53 -11
- data/lib/tasks/jdbc.rake +8 -0
- data/lib/user_system.rb +5 -1
- data/public/javascripts/controls.js +76 -79
- data/public/javascripts/dragdrop.js +166 -167
- data/public/javascripts/effects.js +174 -168
- data/public/javascripts/prototype.js +470 -334
- data/public/stylesheets/mwrt002.css +6 -6
- data/script/dbconsole +3 -0
- data/test/fixtures/backlogs.yml +2 -2
- data/test/fixtures/work_lock_subscriptions.yml +2 -2
- data/test/fixtures/works.yml +6 -6
- data/test/functional/absences_controller_test.rb +1 -1
- data/test/functional/backlogs_controller_test.rb +4 -4
- data/test/functional/customers_controller_test.rb +1 -1
- data/test/functional/dashboard_controller_test.rb +1 -1
- data/test/functional/estimates_controller_test.rb +1 -1
- data/test/functional/groups_controller_test.rb +1 -1
- data/test/functional/parties_controller_test.rb +1 -1
- data/test/functional/periods_controller_test.rb +1 -1
- data/test/functional/public_holidays_controller_test.rb +1 -1
- data/test/functional/search_controller_test.rb +1 -1
- data/test/functional/task_files_controller_test.rb +1 -1
- data/test/functional/tasks_controller_test.rb +6 -6
- data/test/functional/user_controller_test.rb +3 -2
- data/test/functional/welcome_controller_test.rb +1 -1
- data/test/functional/work_locks_controller_test.rb +1 -1
- data/test/functional/works_controller_test.rb +11 -11
- data/test/test_helper.rb +2 -2
- data/test/unit/absence_test.rb +1 -1
- data/test/unit/configuration_test.rb +1 -1
- data/test/unit/customer_test.rb +1 -1
- data/test/unit/estimate_test.rb +1 -1
- data/test/unit/group_test.rb +1 -1
- data/test/unit/party_test.rb +1 -1
- data/test/unit/period_test.rb +1 -1
- data/test/unit/public_holiday_test.rb +1 -1
- data/test/unit/task_file_test.rb +1 -1
- data/test/unit/task_test.rb +1 -1
- data/test/unit/user_test.rb +1 -1
- data/test/unit/work_lock_subscription_test.rb +1 -1
- data/test/unit/work_lock_test.rb +1 -1
- data/test/unit/work_test.rb +8 -8
- data/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +3 -3
- data/vendor/plugins/assert_cookie/lib/assert_cookie.rb +2 -2
- data/vendor/plugins/auto_complete/README +23 -0
- data/vendor/plugins/auto_complete/Rakefile +22 -0
- data/vendor/plugins/auto_complete/init.rb +2 -0
- data/vendor/plugins/auto_complete/lib/auto_complete.rb +47 -0
- data/vendor/plugins/auto_complete/lib/auto_complete_macros_helper.rb +143 -0
- data/vendor/plugins/auto_complete/test/auto_complete_test.rb +67 -0
- data/vendor/plugins/backlog_jira/init.rb +4 -0
- data/vendor/plugins/backlog_jira/{tasks → lib/tasks}/backlog_jira_tasks.rake +0 -0
- data/vendor/plugins/has_history/{tasks → lib/tasks}/has_history_tasks.rake +0 -0
- metadata +745 -817
- data/#SearchRequest.xml# +0 -3443
- data/app/controllers/application.rb~ +0 -207
- data/app/controllers/work_accounts_controller.rb +0 -58
- data/app/helpers/work_accounts_helper.rb +0 -2
- data/app/models/work_account.rb +0 -18
- data/app/models/work_lock_subscription.rb +0 -3
- data/app/views/work_accounts/_form.rhtml +0 -16
- data/app/views/work_accounts/_name_list.rhtml +0 -5
- data/app/views/work_accounts/_title.rhtml +0 -5
- data/app/views/work_accounts/edit.rhtml +0 -12
- data/app/views/work_accounts/list.rhtml +0 -31
- data/app/views/work_accounts/new.rhtml +0 -10
- data/app/views/work_accounts/show.rhtml +0 -50
- data/config/environments/localization_environment.rb +0 -10
- data/jira.log +0 -98246
- data/lang/en.yaml +0 -147
- data/lang/localizations.yaml +0 -2
- data/lang/no.yaml +0 -146
- data/lib/localization.rb +0 -88
- data/test/fixtures/work_accounts.yml +0 -7
- data/test/functional/work_accounts_controller_test.rb +0 -94
- data/test/unit/localization_test.rb +0 -47
- data/test/unit/work_account_test.rb +0 -10
|
@@ -1,10 +1,46 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'active_record/fixtures'
|
|
3
|
+
|
|
1
4
|
# This library makes an ActiveRecord subclass model use one table per subclass level.
|
|
2
5
|
# Instances are instances of the _super class_, with a proxy instance handling the subclass attributes
|
|
3
6
|
# and method calls.
|
|
4
7
|
|
|
8
|
+
# I did get this file from someone else before modyfying it, but I cannot remember who.
|
|
9
|
+
# Credits go to whomever feels they deserve it :)
|
|
10
|
+
|
|
5
11
|
class ActiveRecord::Base
|
|
6
12
|
class_inheritable_array :default_eager_loading
|
|
7
13
|
|
|
14
|
+
# FIXME(uwe): Patch ActiveRecord::Base to accept an array of mixed symbols and strings
|
|
15
|
+
# FIXME(uwe): Works with ActiveRecord 2.3.8
|
|
16
|
+
def self.add_joins!(sql, joins, scope = :auto)
|
|
17
|
+
scope = scope(:find) if :auto == scope
|
|
18
|
+
merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins])
|
|
19
|
+
case merged_joins
|
|
20
|
+
when Symbol, Hash, Array
|
|
21
|
+
|
|
22
|
+
# BEGIN Original code
|
|
23
|
+
# if array_of_strings?(merged_joins)
|
|
24
|
+
# sql << merged_joins.join(' ') + " "
|
|
25
|
+
# else
|
|
26
|
+
# join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
|
|
27
|
+
# sql << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
|
|
28
|
+
# end
|
|
29
|
+
# END Original code
|
|
30
|
+
|
|
31
|
+
# BEGIN New code
|
|
32
|
+
if merged_joins.is_a?(Array)
|
|
33
|
+
merged_joins.delete_if { |join| sql << " #{join} " if join.is_a?(String) }
|
|
34
|
+
end
|
|
35
|
+
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
|
|
36
|
+
sql << " #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} "
|
|
37
|
+
# END New code
|
|
38
|
+
|
|
39
|
+
when String
|
|
40
|
+
sql << " #{merged_joins} "
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
8
44
|
class << self
|
|
9
45
|
alias_method :has_one_without_cti, :has_one
|
|
10
46
|
|
|
@@ -16,9 +52,10 @@ class ActiveRecord::Base
|
|
|
16
52
|
opts = {}
|
|
17
53
|
params.push(opts)
|
|
18
54
|
end
|
|
19
|
-
opts[:
|
|
20
|
-
opts[:
|
|
21
|
-
opts[:
|
|
55
|
+
opts[:joins] ||= []
|
|
56
|
+
opts[:joins] = [opts[:joins]] unless opts[:joins].is_a?(Array)
|
|
57
|
+
opts[:joins] += default_eager_loading
|
|
58
|
+
opts[:readonly] = false if opts[:readonly].nil?
|
|
22
59
|
end
|
|
23
60
|
find_without_default_eager_loading(*params)
|
|
24
61
|
end
|
|
@@ -63,11 +100,10 @@ class ActiveRecord::Base
|
|
|
63
100
|
if options[:save_before_superclass_callbacks] || true
|
|
64
101
|
# We need the after_save filter for this association to run /before/ any other after_save's already registered on a superclass,
|
|
65
102
|
# and before any after_creates or after_updates. This calls for some hackery:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@inheritable_attributes[:after_update].unshift(proxy_save_callback)
|
|
103
|
+
|
|
104
|
+
proxy_save_callback = after_save_callback_chain.pop
|
|
105
|
+
after_create_callback_chain.unshift(proxy_save_callback)
|
|
106
|
+
after_update_callback_chain.unshift(proxy_save_callback)
|
|
71
107
|
end
|
|
72
108
|
|
|
73
109
|
# adds this to the class-inheritable array of default eager loads:
|
|
@@ -106,7 +142,7 @@ class ActiveRecord::Base
|
|
|
106
142
|
def method_missing(method_symbol, *parameters)
|
|
107
143
|
if method_symbol.to_s =~ /^find_by_(.+)/
|
|
108
144
|
attributes = $1.split('_and_')
|
|
109
|
-
super_attributes = attributes & columns.map
|
|
145
|
+
super_attributes = attributes & columns.map{|c| c.name}
|
|
110
146
|
sub_attributes = attributes - super_attributes
|
|
111
147
|
if super_attributes.size > 0
|
|
112
148
|
# TODO (uwe): Only use super attributes first
|
|
@@ -128,7 +164,7 @@ class ActiveRecord::Base
|
|
|
128
164
|
method_missing_super(method_symbol, *parameters)
|
|
129
165
|
end
|
|
130
166
|
end
|
|
131
|
-
# TODO (uwe): validates_uniqueness_of should only be delegated for
|
|
167
|
+
# TODO (uwe): validates_uniqueness_of should only be delegated for columns not in super class???
|
|
132
168
|
delegate :validates_uniqueness_of, {:to => #{proxy_class_name}}
|
|
133
169
|
|
|
134
170
|
delegate :foreign_keys, {:to => #{proxy_class_name}}
|
|
@@ -178,4 +214,10 @@ class ActiveRecord::Base
|
|
|
178
214
|
end
|
|
179
215
|
end
|
|
180
216
|
end
|
|
181
|
-
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
class Fixtures
|
|
220
|
+
def primary_key_name
|
|
221
|
+
@connection.primary_key(@table_name)
|
|
222
|
+
end
|
|
223
|
+
end
|
data/lib/tasks/jdbc.rake
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# This file was generated by the "jdbc" generator, which is provided
|
|
2
|
+
# by the activerecord-jdbc-adapter gem.
|
|
3
|
+
#
|
|
4
|
+
# This file allows you to use Rails' various db:* tasks with JDBC.
|
|
5
|
+
if defined?(JRUBY_VERSION)
|
|
6
|
+
require 'jdbc_adapter'
|
|
7
|
+
require 'jdbc_adapter/rake_tasks'
|
|
8
|
+
end
|
data/lib/user_system.rb
CHANGED
|
@@ -49,6 +49,8 @@ module UserSystem
|
|
|
49
49
|
cookies[:autologin]
|
|
50
50
|
when Hash:
|
|
51
51
|
cookies[:autologin][:value].first
|
|
52
|
+
when CGI::Cookie
|
|
53
|
+
cookies[:autologin].first[:value].first
|
|
52
54
|
else
|
|
53
55
|
raise "Unknown cookie class: #{cookie.class}"
|
|
54
56
|
end
|
|
@@ -57,6 +59,8 @@ module UserSystem
|
|
|
57
59
|
cookies[:token]
|
|
58
60
|
when Hash:
|
|
59
61
|
cookies[:token][:value].first
|
|
62
|
+
when CGI::Cookie
|
|
63
|
+
cookies[:token].first[:value].first
|
|
60
64
|
else
|
|
61
65
|
raise "Unknown cookie class: #{cookie.class}"
|
|
62
66
|
end
|
|
@@ -87,7 +91,7 @@ module UserSystem
|
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
def current_user= user
|
|
90
|
-
session[:user_id] = user && user.id if
|
|
94
|
+
session[:user_id] = user && user.id if self.respond_to?(:session)
|
|
91
95
|
Thread.current[:user] = user
|
|
92
96
|
end
|
|
93
97
|
|
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
// script.aculo.us
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
|
5
|
-
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
|
1
|
+
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
2
|
+
// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
|
3
|
+
// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
|
|
6
4
|
// Contributors:
|
|
7
5
|
// Richard Livsey
|
|
8
6
|
// Rahul Bhargava
|
|
9
7
|
// Rob Wills
|
|
10
|
-
//
|
|
8
|
+
//
|
|
11
9
|
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
|
12
10
|
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
|
13
11
|
|
|
14
|
-
// Autocompleter.Base handles all the autocompletion functionality
|
|
12
|
+
// Autocompleter.Base handles all the autocompletion functionality
|
|
15
13
|
// that's independent of the data source for autocompletion. This
|
|
16
14
|
// includes drawing the autocompletion menu, observing keyboard
|
|
17
15
|
// and mouse events, and similar.
|
|
18
16
|
//
|
|
19
|
-
// Specific autocompleters need to provide, at the very least,
|
|
17
|
+
// Specific autocompleters need to provide, at the very least,
|
|
20
18
|
// a getUpdatedChoices function that will be invoked every time
|
|
21
|
-
// the text inside the monitored textbox changes. This method
|
|
19
|
+
// the text inside the monitored textbox changes. This method
|
|
22
20
|
// should get the text for which to provide autocompletion by
|
|
23
21
|
// invoking this.getToken(), NOT by directly accessing
|
|
24
22
|
// this.element.value. This is to allow incremental tokenized
|
|
@@ -32,23 +30,23 @@
|
|
|
32
30
|
// will incrementally autocomplete with a comma as the token.
|
|
33
31
|
// Additionally, ',' in the above example can be replaced with
|
|
34
32
|
// a token array, e.g. { tokens: [',', '\n'] } which
|
|
35
|
-
// enables autocompletion on multiple tokens. This is most
|
|
36
|
-
// useful when one of the tokens is \n (a newline), as it
|
|
33
|
+
// enables autocompletion on multiple tokens. This is most
|
|
34
|
+
// useful when one of the tokens is \n (a newline), as it
|
|
37
35
|
// allows smart autocompletion after linebreaks.
|
|
38
36
|
|
|
39
37
|
if(typeof Effect == 'undefined')
|
|
40
38
|
throw("controls.js requires including script.aculo.us' effects.js library");
|
|
41
39
|
|
|
42
|
-
var Autocompleter = { }
|
|
40
|
+
var Autocompleter = { };
|
|
43
41
|
Autocompleter.Base = Class.create({
|
|
44
42
|
baseInitialize: function(element, update, options) {
|
|
45
|
-
element = $(element)
|
|
46
|
-
this.element = element;
|
|
47
|
-
this.update = $(update);
|
|
48
|
-
this.hasFocus = false;
|
|
49
|
-
this.changed = false;
|
|
50
|
-
this.active = false;
|
|
51
|
-
this.index = 0;
|
|
43
|
+
element = $(element);
|
|
44
|
+
this.element = element;
|
|
45
|
+
this.update = $(update);
|
|
46
|
+
this.hasFocus = false;
|
|
47
|
+
this.changed = false;
|
|
48
|
+
this.active = false;
|
|
49
|
+
this.index = 0;
|
|
52
50
|
this.entryCount = 0;
|
|
53
51
|
this.oldElementValue = this.element.value;
|
|
54
52
|
|
|
@@ -61,42 +59,42 @@ Autocompleter.Base = Class.create({
|
|
|
61
59
|
this.options.tokens = this.options.tokens || [];
|
|
62
60
|
this.options.frequency = this.options.frequency || 0.4;
|
|
63
61
|
this.options.minChars = this.options.minChars || 1;
|
|
64
|
-
this.options.onShow = this.options.onShow ||
|
|
65
|
-
function(element, update){
|
|
62
|
+
this.options.onShow = this.options.onShow ||
|
|
63
|
+
function(element, update){
|
|
66
64
|
if(!update.style.position || update.style.position=='absolute') {
|
|
67
65
|
update.style.position = 'absolute';
|
|
68
66
|
Position.clone(element, update, {
|
|
69
|
-
setHeight: false,
|
|
67
|
+
setHeight: false,
|
|
70
68
|
offsetTop: element.offsetHeight
|
|
71
69
|
});
|
|
72
70
|
}
|
|
73
71
|
Effect.Appear(update,{duration:0.15});
|
|
74
72
|
};
|
|
75
|
-
this.options.onHide = this.options.onHide ||
|
|
73
|
+
this.options.onHide = this.options.onHide ||
|
|
76
74
|
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
|
|
77
75
|
|
|
78
|
-
if(typeof(this.options.tokens) == 'string')
|
|
76
|
+
if(typeof(this.options.tokens) == 'string')
|
|
79
77
|
this.options.tokens = new Array(this.options.tokens);
|
|
80
78
|
// Force carriage returns as token delimiters anyway
|
|
81
79
|
if (!this.options.tokens.include('\n'))
|
|
82
80
|
this.options.tokens.push('\n');
|
|
83
81
|
|
|
84
82
|
this.observer = null;
|
|
85
|
-
|
|
83
|
+
|
|
86
84
|
this.element.setAttribute('autocomplete','off');
|
|
87
85
|
|
|
88
86
|
Element.hide(this.update);
|
|
89
87
|
|
|
90
88
|
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
|
|
91
|
-
Event.observe(this.element, '
|
|
89
|
+
Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
|
|
92
90
|
},
|
|
93
91
|
|
|
94
92
|
show: function() {
|
|
95
93
|
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
|
96
|
-
if(!this.iefix &&
|
|
94
|
+
if(!this.iefix &&
|
|
97
95
|
(Prototype.Browser.IE) &&
|
|
98
96
|
(Element.getStyle(this.update, 'position')=='absolute')) {
|
|
99
|
-
new Insertion.After(this.update,
|
|
97
|
+
new Insertion.After(this.update,
|
|
100
98
|
'<iframe id="' + this.update.id + '_iefix" '+
|
|
101
99
|
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
|
|
102
100
|
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
|
|
@@ -104,7 +102,7 @@ Autocompleter.Base = Class.create({
|
|
|
104
102
|
}
|
|
105
103
|
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
|
|
106
104
|
},
|
|
107
|
-
|
|
105
|
+
|
|
108
106
|
fixIEOverlapping: function() {
|
|
109
107
|
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
|
|
110
108
|
this.iefix.style.zIndex = 1;
|
|
@@ -130,7 +128,6 @@ Autocompleter.Base = Class.create({
|
|
|
130
128
|
if(this.active)
|
|
131
129
|
switch(event.keyCode) {
|
|
132
130
|
case Event.KEY_TAB:
|
|
133
|
-
return;
|
|
134
131
|
case Event.KEY_RETURN:
|
|
135
132
|
this.selectEntry();
|
|
136
133
|
Event.stop(event);
|
|
@@ -145,23 +142,23 @@ Autocompleter.Base = Class.create({
|
|
|
145
142
|
case Event.KEY_UP:
|
|
146
143
|
this.markPrevious();
|
|
147
144
|
this.render();
|
|
148
|
-
|
|
145
|
+
Event.stop(event);
|
|
149
146
|
return;
|
|
150
147
|
case Event.KEY_DOWN:
|
|
151
148
|
this.markNext();
|
|
152
149
|
this.render();
|
|
153
|
-
|
|
150
|
+
Event.stop(event);
|
|
154
151
|
return;
|
|
155
152
|
}
|
|
156
|
-
else
|
|
157
|
-
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
|
153
|
+
else
|
|
154
|
+
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
|
158
155
|
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
|
|
159
156
|
|
|
160
157
|
this.changed = true;
|
|
161
158
|
this.hasFocus = true;
|
|
162
159
|
|
|
163
160
|
if(this.observer) clearTimeout(this.observer);
|
|
164
|
-
this.observer =
|
|
161
|
+
this.observer =
|
|
165
162
|
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
|
166
163
|
},
|
|
167
164
|
|
|
@@ -173,35 +170,35 @@ Autocompleter.Base = Class.create({
|
|
|
173
170
|
|
|
174
171
|
onHover: function(event) {
|
|
175
172
|
var element = Event.findElement(event, 'LI');
|
|
176
|
-
if(this.index != element.autocompleteIndex)
|
|
173
|
+
if(this.index != element.autocompleteIndex)
|
|
177
174
|
{
|
|
178
175
|
this.index = element.autocompleteIndex;
|
|
179
176
|
this.render();
|
|
180
177
|
}
|
|
181
178
|
Event.stop(event);
|
|
182
179
|
},
|
|
183
|
-
|
|
180
|
+
|
|
184
181
|
onClick: function(event) {
|
|
185
182
|
var element = Event.findElement(event, 'LI');
|
|
186
183
|
this.index = element.autocompleteIndex;
|
|
187
184
|
this.selectEntry();
|
|
188
185
|
this.hide();
|
|
189
186
|
},
|
|
190
|
-
|
|
187
|
+
|
|
191
188
|
onBlur: function(event) {
|
|
192
189
|
// needed to make click events working
|
|
193
190
|
setTimeout(this.hide.bind(this), 250);
|
|
194
191
|
this.hasFocus = false;
|
|
195
|
-
this.active = false;
|
|
196
|
-
},
|
|
197
|
-
|
|
192
|
+
this.active = false;
|
|
193
|
+
},
|
|
194
|
+
|
|
198
195
|
render: function() {
|
|
199
196
|
if(this.entryCount > 0) {
|
|
200
197
|
for (var i = 0; i < this.entryCount; i++)
|
|
201
|
-
this.index==i ?
|
|
202
|
-
Element.addClassName(this.getEntry(i),"selected") :
|
|
198
|
+
this.index==i ?
|
|
199
|
+
Element.addClassName(this.getEntry(i),"selected") :
|
|
203
200
|
Element.removeClassName(this.getEntry(i),"selected");
|
|
204
|
-
if(this.hasFocus) {
|
|
201
|
+
if(this.hasFocus) {
|
|
205
202
|
this.show();
|
|
206
203
|
this.active = true;
|
|
207
204
|
}
|
|
@@ -210,27 +207,27 @@ Autocompleter.Base = Class.create({
|
|
|
210
207
|
this.hide();
|
|
211
208
|
}
|
|
212
209
|
},
|
|
213
|
-
|
|
210
|
+
|
|
214
211
|
markPrevious: function() {
|
|
215
|
-
if(this.index > 0) this.index
|
|
212
|
+
if(this.index > 0) this.index--;
|
|
216
213
|
else this.index = this.entryCount-1;
|
|
217
214
|
this.getEntry(this.index).scrollIntoView(true);
|
|
218
215
|
},
|
|
219
|
-
|
|
216
|
+
|
|
220
217
|
markNext: function() {
|
|
221
|
-
if(this.index < this.entryCount-1) this.index
|
|
218
|
+
if(this.index < this.entryCount-1) this.index++;
|
|
222
219
|
else this.index = 0;
|
|
223
220
|
this.getEntry(this.index).scrollIntoView(false);
|
|
224
221
|
},
|
|
225
|
-
|
|
222
|
+
|
|
226
223
|
getEntry: function(index) {
|
|
227
224
|
return this.update.firstChild.childNodes[index];
|
|
228
225
|
},
|
|
229
|
-
|
|
226
|
+
|
|
230
227
|
getCurrentEntry: function() {
|
|
231
228
|
return this.getEntry(this.index);
|
|
232
229
|
},
|
|
233
|
-
|
|
230
|
+
|
|
234
231
|
selectEntry: function() {
|
|
235
232
|
this.active = false;
|
|
236
233
|
this.updateElement(this.getCurrentEntry());
|
|
@@ -247,7 +244,7 @@ Autocompleter.Base = Class.create({
|
|
|
247
244
|
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
|
|
248
245
|
} else
|
|
249
246
|
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
|
250
|
-
|
|
247
|
+
|
|
251
248
|
var bounds = this.getTokenBounds();
|
|
252
249
|
if (bounds[0] != -1) {
|
|
253
250
|
var newValue = this.element.value.substr(0, bounds[0]);
|
|
@@ -260,7 +257,7 @@ Autocompleter.Base = Class.create({
|
|
|
260
257
|
}
|
|
261
258
|
this.oldElementValue = this.element.value;
|
|
262
259
|
this.element.focus();
|
|
263
|
-
|
|
260
|
+
|
|
264
261
|
if (this.options.afterUpdateElement)
|
|
265
262
|
this.options.afterUpdateElement(this.element, selectedElement);
|
|
266
263
|
},
|
|
@@ -272,20 +269,20 @@ Autocompleter.Base = Class.create({
|
|
|
272
269
|
Element.cleanWhitespace(this.update.down());
|
|
273
270
|
|
|
274
271
|
if(this.update.firstChild && this.update.down().childNodes) {
|
|
275
|
-
this.entryCount =
|
|
272
|
+
this.entryCount =
|
|
276
273
|
this.update.down().childNodes.length;
|
|
277
274
|
for (var i = 0; i < this.entryCount; i++) {
|
|
278
275
|
var entry = this.getEntry(i);
|
|
279
276
|
entry.autocompleteIndex = i;
|
|
280
277
|
this.addObservers(entry);
|
|
281
278
|
}
|
|
282
|
-
} else {
|
|
279
|
+
} else {
|
|
283
280
|
this.entryCount = 0;
|
|
284
281
|
}
|
|
285
282
|
|
|
286
283
|
this.stopIndicator();
|
|
287
284
|
this.index = 0;
|
|
288
|
-
|
|
285
|
+
|
|
289
286
|
if(this.entryCount==1 && this.options.autoSelect) {
|
|
290
287
|
this.selectEntry();
|
|
291
288
|
this.hide();
|
|
@@ -301,7 +298,7 @@ Autocompleter.Base = Class.create({
|
|
|
301
298
|
},
|
|
302
299
|
|
|
303
300
|
onObserverEvent: function() {
|
|
304
|
-
this.changed = false;
|
|
301
|
+
this.changed = false;
|
|
305
302
|
this.tokenBounds = null;
|
|
306
303
|
if(this.getToken().length>=this.options.minChars) {
|
|
307
304
|
this.getUpdatedChoices();
|
|
@@ -354,16 +351,16 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
|
|
354
351
|
|
|
355
352
|
getUpdatedChoices: function() {
|
|
356
353
|
this.startIndicator();
|
|
357
|
-
|
|
358
|
-
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
|
354
|
+
|
|
355
|
+
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
|
359
356
|
encodeURIComponent(this.getToken());
|
|
360
357
|
|
|
361
358
|
this.options.parameters = this.options.callback ?
|
|
362
359
|
this.options.callback(this.element, entry) : entry;
|
|
363
360
|
|
|
364
|
-
if(this.options.defaultParams)
|
|
361
|
+
if(this.options.defaultParams)
|
|
365
362
|
this.options.parameters += '&' + this.options.defaultParams;
|
|
366
|
-
|
|
363
|
+
|
|
367
364
|
new Ajax.Request(this.url, this.options);
|
|
368
365
|
},
|
|
369
366
|
|
|
@@ -385,7 +382,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
|
|
385
382
|
// - choices - How many autocompletion choices to offer
|
|
386
383
|
//
|
|
387
384
|
// - partialSearch - If false, the autocompleter will match entered
|
|
388
|
-
// text only at the beginning of strings in the
|
|
385
|
+
// text only at the beginning of strings in the
|
|
389
386
|
// autocomplete array. Defaults to true, which will
|
|
390
387
|
// match text at the beginning of any *word* in the
|
|
391
388
|
// strings in the autocomplete array. If you want to
|
|
@@ -402,7 +399,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
|
|
402
399
|
// - ignoreCase - Whether to ignore case when autocompleting.
|
|
403
400
|
// Defaults to true.
|
|
404
401
|
//
|
|
405
|
-
// It's possible to pass in a custom function as the 'selector'
|
|
402
|
+
// It's possible to pass in a custom function as the 'selector'
|
|
406
403
|
// option, if you prefer to write your own autocompletion logic.
|
|
407
404
|
// In that case, the other options above will not apply unless
|
|
408
405
|
// you support them.
|
|
@@ -430,20 +427,20 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
|
|
|
430
427
|
var entry = instance.getToken();
|
|
431
428
|
var count = 0;
|
|
432
429
|
|
|
433
|
-
for (var i = 0; i < instance.options.array.length &&
|
|
434
|
-
ret.length < instance.options.choices ; i++) {
|
|
430
|
+
for (var i = 0; i < instance.options.array.length &&
|
|
431
|
+
ret.length < instance.options.choices ; i++) {
|
|
435
432
|
|
|
436
433
|
var elem = instance.options.array[i];
|
|
437
|
-
var foundPos = instance.options.ignoreCase ?
|
|
438
|
-
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
|
434
|
+
var foundPos = instance.options.ignoreCase ?
|
|
435
|
+
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
|
439
436
|
elem.indexOf(entry);
|
|
440
437
|
|
|
441
438
|
while (foundPos != -1) {
|
|
442
|
-
if (foundPos == 0 && elem.length != entry.length) {
|
|
443
|
-
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
|
439
|
+
if (foundPos == 0 && elem.length != entry.length) {
|
|
440
|
+
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
|
444
441
|
elem.substr(entry.length) + "</li>");
|
|
445
442
|
break;
|
|
446
|
-
} else if (entry.length >= instance.options.partialChars &&
|
|
443
|
+
} else if (entry.length >= instance.options.partialChars &&
|
|
447
444
|
instance.options.partialSearch && foundPos != -1) {
|
|
448
445
|
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
|
|
449
446
|
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
|
|
@@ -453,14 +450,14 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
|
|
|
453
450
|
}
|
|
454
451
|
}
|
|
455
452
|
|
|
456
|
-
foundPos = instance.options.ignoreCase ?
|
|
457
|
-
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
|
453
|
+
foundPos = instance.options.ignoreCase ?
|
|
454
|
+
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
|
458
455
|
elem.indexOf(entry, foundPos + 1);
|
|
459
456
|
|
|
460
457
|
}
|
|
461
458
|
}
|
|
462
459
|
if (partial.length)
|
|
463
|
-
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
|
|
460
|
+
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
|
|
464
461
|
return "<ul>" + ret.join('') + "</ul>";
|
|
465
462
|
}
|
|
466
463
|
}, options || { });
|
|
@@ -477,7 +474,7 @@ Field.scrollFreeActivate = function(field) {
|
|
|
477
474
|
setTimeout(function() {
|
|
478
475
|
Field.activate(field);
|
|
479
476
|
}, 1);
|
|
480
|
-
}
|
|
477
|
+
};
|
|
481
478
|
|
|
482
479
|
Ajax.InPlaceEditor = Class.create({
|
|
483
480
|
initialize: function(element, url, options) {
|
|
@@ -607,7 +604,7 @@ Ajax.InPlaceEditor = Class.create({
|
|
|
607
604
|
this.triggerCallback('onEnterHover');
|
|
608
605
|
},
|
|
609
606
|
getText: function() {
|
|
610
|
-
return this.element.innerHTML;
|
|
607
|
+
return this.element.innerHTML.unescapeHTML();
|
|
611
608
|
},
|
|
612
609
|
handleAJAXFailure: function(transport) {
|
|
613
610
|
this.triggerCallback('onFailure', transport);
|
|
@@ -783,7 +780,7 @@ Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
|
|
|
783
780
|
onSuccess: function(transport) {
|
|
784
781
|
var js = transport.responseText.strip();
|
|
785
782
|
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
|
|
786
|
-
throw
|
|
783
|
+
throw('Server returned an invalid collection representation.');
|
|
787
784
|
this._collection = eval(js);
|
|
788
785
|
this.checkForExternalText();
|
|
789
786
|
}.bind(this),
|
|
@@ -940,7 +937,7 @@ Ajax.InPlaceCollectionEditor.DefaultOptions = {
|
|
|
940
937
|
loadingCollectionText: 'Loading options...'
|
|
941
938
|
};
|
|
942
939
|
|
|
943
|
-
// Delayed observer, like Form.Element.Observer,
|
|
940
|
+
// Delayed observer, like Form.Element.Observer,
|
|
944
941
|
// but waits for delay after last key input
|
|
945
942
|
// Ideal for live-search fields
|
|
946
943
|
|
|
@@ -950,7 +947,7 @@ Form.Element.DelayedObserver = Class.create({
|
|
|
950
947
|
this.element = $(element);
|
|
951
948
|
this.callback = callback;
|
|
952
949
|
this.timer = null;
|
|
953
|
-
this.lastValue = $F(this.element);
|
|
950
|
+
this.lastValue = $F(this.element);
|
|
954
951
|
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
|
|
955
952
|
},
|
|
956
953
|
delayedListener: function(event) {
|
|
@@ -963,4 +960,4 @@ Form.Element.DelayedObserver = Class.create({
|
|
|
963
960
|
this.timer = null;
|
|
964
961
|
this.callback(this.element, $F(this.element));
|
|
965
962
|
}
|
|
966
|
-
});
|
|
963
|
+
});
|