discuss 0.0.1

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.
Files changed (151) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +153 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/discuss/application.js +3 -0
  6. data/app/assets/javascripts/discuss/chosen.jquery.js +1104 -0
  7. data/app/assets/javascripts/discuss/compose.coffee +21 -0
  8. data/app/assets/javascripts/discuss/discuss.chosen.coffee +2 -0
  9. data/app/assets/javascripts/discuss/discuss.coffee +2 -0
  10. data/app/assets/javascripts/discuss/messages.coffee +0 -0
  11. data/app/assets/stylesheets/discuss/application.css +13 -0
  12. data/app/assets/stylesheets/discuss/chosen.css +439 -0
  13. data/app/controllers/discuss/application_controller.rb +11 -0
  14. data/app/controllers/discuss/mailboxes_controller.rb +30 -0
  15. data/app/controllers/discuss/messages_controller.rb +85 -0
  16. data/app/helpers/discuss/application_helper.rb +7 -0
  17. data/app/models/discuss/conversation.rb +29 -0
  18. data/app/models/discuss/mailbox.rb +33 -0
  19. data/app/models/discuss/message.rb +135 -0
  20. data/app/services/discuss/message_sender.rb +33 -0
  21. data/app/views/discuss/mailboxes/show.html.haml +24 -0
  22. data/app/views/discuss/messages/_form.html.haml +18 -0
  23. data/app/views/discuss/messages/edit.html.haml +1 -0
  24. data/app/views/discuss/messages/new.html.haml +1 -0
  25. data/app/views/discuss/messages/show.html.haml +28 -0
  26. data/app/views/discuss/shared/_nav.haml +8 -0
  27. data/config/routes.rb +15 -0
  28. data/db/migrate/20130419055252_setup_discuss.rb +22 -0
  29. data/lib/discuss.rb +4 -0
  30. data/lib/discuss/engine.rb +9 -0
  31. data/lib/discuss/models/discussable.rb +29 -0
  32. data/lib/discuss/version.rb +3 -0
  33. data/lib/generators/discuss/views_generator.rb +8 -0
  34. data/lib/tasks/discuss_tasks.rake +4 -0
  35. data/test/discuss_test.rb +7 -0
  36. data/test/dummy/README.rdoc +28 -0
  37. data/test/dummy/Rakefile +6 -0
  38. data/test/dummy/app/assets/javascripts/application.js +5 -0
  39. data/test/dummy/app/assets/javascripts/chosen.jquery.js +1104 -0
  40. data/test/dummy/app/assets/javascripts/compose.coffee +21 -0
  41. data/test/dummy/app/assets/javascripts/discuss.chosen.coffee +2 -0
  42. data/test/dummy/app/assets/javascripts/discuss.coffee +2 -0
  43. data/test/dummy/app/assets/javascripts/messages.coffee +0 -0
  44. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  45. data/test/dummy/app/assets/stylesheets/chosen.css +439 -0
  46. data/test/dummy/app/assets/stylesheets/discuss.css +41 -0
  47. data/test/dummy/app/controllers/application_controller.rb +5 -0
  48. data/test/dummy/app/helpers/application_helper.rb +2 -0
  49. data/test/dummy/app/models/user.rb +22 -0
  50. data/test/dummy/app/views/layouts/application.html.erb +17 -0
  51. data/test/dummy/bin/bundle +3 -0
  52. data/test/dummy/bin/rails +4 -0
  53. data/test/dummy/bin/rake +4 -0
  54. data/test/dummy/config.ru +4 -0
  55. data/test/dummy/config/application.rb +23 -0
  56. data/test/dummy/config/boot.rb +9 -0
  57. data/test/dummy/config/database.yml +25 -0
  58. data/test/dummy/config/environment.rb +5 -0
  59. data/test/dummy/config/environments/development.rb +27 -0
  60. data/test/dummy/config/environments/production.rb +80 -0
  61. data/test/dummy/config/environments/test.rb +36 -0
  62. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  64. data/test/dummy/config/initializers/inflections.rb +16 -0
  65. data/test/dummy/config/initializers/mime_types.rb +5 -0
  66. data/test/dummy/config/initializers/secret_token.rb +12 -0
  67. data/test/dummy/config/initializers/session_store.rb +3 -0
  68. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/test/dummy/config/locales/en.yml +23 -0
  70. data/test/dummy/config/routes.rb +4 -0
  71. data/test/dummy/db/development.sqlite3 +0 -0
  72. data/test/dummy/db/migrate/20130428235128_create_users.rb +11 -0
  73. data/test/dummy/db/schema.rb +24 -0
  74. data/test/dummy/db/test.sqlite3 +0 -0
  75. data/test/dummy/log/development.log +16219 -0
  76. data/test/dummy/log/test.log +191354 -0
  77. data/test/dummy/public/404.html +27 -0
  78. data/test/dummy/public/422.html +26 -0
  79. data/test/dummy/public/500.html +26 -0
  80. data/test/dummy/public/favicon.ico +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/0a28667732e1be8938cde061b6f996df +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/0ddd7cc29057a69bd29fde03bf0f4c00 +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/0de2f69502366965bb7fae2623bc190c +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/0ee691067e6ec8f03df58bc94badd25d +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/1b77abb6bee52fa8d68ee7e81077ff20 +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/271bb8f72971af6089be8d1b85788bec +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/2a499e57eb2664f139ab0e74571faa77 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/32b6af14546cb11e773fb3799f041132 +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/4728f8b9616c35f685674fbeecaa3c47 +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/4e9a3e121da30d3a85273a5c283da214 +0 -0
  94. data/test/dummy/tmp/cache/assets/development/sprockets/5620ff4659033b350ea3031ecaeb5127 +0 -0
  95. data/test/dummy/tmp/cache/assets/development/sprockets/596293af7e4dcfa45880435ae753f876 +0 -0
  96. data/test/dummy/tmp/cache/assets/development/sprockets/614995c5e7b1b4f5b12ce060404706cc +0 -0
  97. data/test/dummy/tmp/cache/assets/development/sprockets/6b9e24a8aad25948823e1a93c8be731e +0 -0
  98. data/test/dummy/tmp/cache/assets/development/sprockets/78a00003621b318a297e05cfedb0d1fd +0 -0
  99. data/test/dummy/tmp/cache/assets/development/sprockets/794654d117cd2ec6a9a00e485d9f4485 +0 -0
  100. data/test/dummy/tmp/cache/assets/development/sprockets/79ae3a9f48e9b9e8ef2922c844b1895f +0 -0
  101. data/test/dummy/tmp/cache/assets/development/sprockets/9b5889bea21f2af8068646890752932c +0 -0
  102. data/test/dummy/tmp/cache/assets/development/sprockets/9fd02d20091838d6411df2d23a5364d5 +0 -0
  103. data/test/dummy/tmp/cache/assets/development/sprockets/a02345b542298f25d3f701ee680c44c0 +0 -0
  104. data/test/dummy/tmp/cache/assets/development/sprockets/a80359c0e09ddf510ce63de09a368d4c +0 -0
  105. data/test/dummy/tmp/cache/assets/development/sprockets/ad2a9bfe4169e0a5bc66efd35c83fe38 +0 -0
  106. data/test/dummy/tmp/cache/assets/development/sprockets/b1794788ec8ce362aceaffa31c7381e9 +0 -0
  107. data/test/dummy/tmp/cache/assets/development/sprockets/b284f477944d67f25c0672dba1a2dab4 +0 -0
  108. data/test/dummy/tmp/cache/assets/development/sprockets/b2b1f16cf54d69c151ca7f42fb2f8381 +0 -0
  109. data/test/dummy/tmp/cache/assets/development/sprockets/b4767dfdb540517d26dc8c5365736f53 +0 -0
  110. data/test/dummy/tmp/cache/assets/development/sprockets/bab78b46d2a6282e5df747dd8b6d5abf +0 -0
  111. data/test/dummy/tmp/cache/assets/development/sprockets/c9a09977565da30179ad7fdb9f79ae0d +0 -0
  112. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  113. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  114. data/test/dummy/tmp/cache/assets/development/sprockets/d9c8047218dc90a46a6725543638de45 +0 -0
  115. data/test/dummy/tmp/cache/assets/development/sprockets/e5b181eb056bbd6ffad37ed146b0342e +0 -0
  116. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  117. data/test/dummy/tmp/cache/assets/test/sprockets/0a28667732e1be8938cde061b6f996df +0 -0
  118. data/test/dummy/tmp/cache/assets/test/sprockets/0ddd7cc29057a69bd29fde03bf0f4c00 +0 -0
  119. data/test/dummy/tmp/cache/assets/test/sprockets/0de2f69502366965bb7fae2623bc190c +0 -0
  120. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  121. data/test/dummy/tmp/cache/assets/test/sprockets/1b77abb6bee52fa8d68ee7e81077ff20 +0 -0
  122. data/test/dummy/tmp/cache/assets/test/sprockets/271bb8f72971af6089be8d1b85788bec +0 -0
  123. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  124. data/test/dummy/tmp/cache/assets/test/sprockets/32b6af14546cb11e773fb3799f041132 +0 -0
  125. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  126. data/test/dummy/tmp/cache/assets/test/sprockets/4728f8b9616c35f685674fbeecaa3c47 +0 -0
  127. data/test/dummy/tmp/cache/assets/test/sprockets/5620ff4659033b350ea3031ecaeb5127 +0 -0
  128. data/test/dummy/tmp/cache/assets/test/sprockets/596293af7e4dcfa45880435ae753f876 +0 -0
  129. data/test/dummy/tmp/cache/assets/test/sprockets/78a00003621b318a297e05cfedb0d1fd +0 -0
  130. data/test/dummy/tmp/cache/assets/test/sprockets/794654d117cd2ec6a9a00e485d9f4485 +0 -0
  131. data/test/dummy/tmp/cache/assets/test/sprockets/79ae3a9f48e9b9e8ef2922c844b1895f +0 -0
  132. data/test/dummy/tmp/cache/assets/test/sprockets/9b5889bea21f2af8068646890752932c +0 -0
  133. data/test/dummy/tmp/cache/assets/test/sprockets/9fd02d20091838d6411df2d23a5364d5 +0 -0
  134. data/test/dummy/tmp/cache/assets/test/sprockets/a02345b542298f25d3f701ee680c44c0 +0 -0
  135. data/test/dummy/tmp/cache/assets/test/sprockets/a80359c0e09ddf510ce63de09a368d4c +0 -0
  136. data/test/dummy/tmp/cache/assets/test/sprockets/ad2a9bfe4169e0a5bc66efd35c83fe38 +0 -0
  137. data/test/dummy/tmp/cache/assets/test/sprockets/bab78b46d2a6282e5df747dd8b6d5abf +0 -0
  138. data/test/dummy/tmp/cache/assets/test/sprockets/c9a09977565da30179ad7fdb9f79ae0d +0 -0
  139. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  140. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  141. data/test/dummy/tmp/cache/assets/test/sprockets/d9c8047218dc90a46a6725543638de45 +0 -0
  142. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  143. data/test/features/workflow_test.rb +182 -0
  144. data/test/test_helper.rb +68 -0
  145. data/test/unit/discuss/conversation_test.rb +79 -0
  146. data/test/unit/discuss/mailbox_test.rb +72 -0
  147. data/test/unit/discuss/message_test.rb +73 -0
  148. data/test/unit/discuss/recipient_test.rb +56 -0
  149. data/test/unit/discuss/sender_test.rb +106 -0
  150. data/test/unit/helpers/discuss/messages_helper_test.rb +6 -0
  151. metadata +422 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTk0Yjk5NDgxM2IwMDA3NTEyOWEwMTgwODRlZjIxZjc5NzFhZGM2OQ==
5
+ data.tar.gz: !binary |-
6
+ ZWM0YzNhYjRhMTc2NjA1ZDI3ZDU2NDMyNmRkZmFkYzk3ZWI0MDNlZQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YWRkMTJlOGE2NmM5OWUwZDFkMjdjOGExYWYzMDE1NDIxODVkNDJlNzJkZmVh
10
+ YjEzMTNlMmI1MjUwODk2ZjQzY2YyODI0OGMzY2U5OTBiMzIzYjA4MWQ3YjRl
11
+ MDk0NmY3MThkZmRkZjA5ODU4MGEyODg1YmM5M2E2ODZhMTU2ZDg=
12
+ data.tar.gz: !binary |-
13
+ MWYwMDM3MDZiYjZkMjZkNGE1YzM4Mjk1NzczNjQ2ZjU3MGI4M2RhOWFjNDA3
14
+ NzcxZTA0NGU5NzE4MjkzZTA4YzE2MDAzYTIxZmQ5MGE3ODM3NWJlZTQwNjgw
15
+ OTUwZDE0NWM2ZDBkZDI4N2RkNTI3MzFmOTM0MWVjYjM1ZDVjZjk=
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Elle Meredith
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # Discuss
2
+
3
+ We have a table discuss users that will be used to populate the recipients field.
4
+ We are not creating new users via recipients since the user need to exist and be logged in in order to view her messages.
5
+
6
+ If for example we have two users: Batman and Robin and Batman sends a message to Robin. What will be created are two objects:
7
+
8
+ 1. A Message object `where(discuss_user: Batman, sent_at: Time.zone.now)`
9
+ 2. A second Message object `where(dicuss_user: Robin, received_at: Time.zone.now)`
10
+
11
+ When Robin logs in, she can view this message in her inbox.
12
+ The inbox view uses `Mailbox.new(Robin).inbox`
13
+
14
+ Batman's sent messages view will use a similar query: `Mailbox.new(Batman).outbox`
15
+
16
+
17
+ If no recipients are entered, the message will be saved as draft.
18
+ Messages by default are saved as draft until they are delivered (#send!).
19
+
20
+ ## Setup
21
+
22
+ Add the gem to your Gemfile.
23
+
24
+ ```ruby
25
+ gem 'discuss'
26
+ ```
27
+
28
+ Get the migrations
29
+
30
+ ```shell
31
+ rake discuss:install:migrations
32
+ ```
33
+
34
+ And run them on in your app
35
+
36
+ ```shell
37
+ rake db:migrate
38
+ ```
39
+
40
+ Add the following to `config/routes.rb`:
41
+
42
+ ```ruby
43
+ mount Discuss::Engine, :at => '/messages'
44
+ ```
45
+
46
+ Define a `current_user` in your `application_controller.rb`:
47
+
48
+ ```ruby
49
+ class ApplicationController < ActionController::Base
50
+
51
+ private
52
+ def current_user
53
+ # Your own implementation
54
+ end
55
+ end
56
+ end
57
+ ```
58
+
59
+ Add the following to `user.rb`:
60
+
61
+ ```ruby
62
+ class User < ActiveRecord::Base
63
+ acts_as_discussable
64
+ end
65
+ ```
66
+
67
+ And lastly add the following to your assets files:
68
+
69
+
70
+ ```ruby
71
+ #app/assets/stylesheets/application.scss
72
+ @import "discuss/application";
73
+
74
+ #app/assets/javascripts/application.js
75
+ //= require discuss/application
76
+ ```
77
+
78
+ If you have problems with your current routes, you might need to add `main_app` to the beginning of your routes.
79
+
80
+ And in our case, all the messages interface should be available at `/messages`
81
+
82
+ ## DSL
83
+
84
+ ```ruby
85
+ @mailbox = Mailbox.new(user)
86
+ @mailbox.inbox
87
+ @mailbox.outbox
88
+ @mailbox.drafts
89
+ @mailbox.trash
90
+
91
+ @mailbox.empty_trash! # => deletes all messages that are already trashed
92
+
93
+ @message = User.message.create(body: 'lorem ipsum', recipients: [@user1, @user2]) # => creates a draft
94
+ @message.send! # delivers a message
95
+
96
+ @message.trash! # => moves the message to the trash
97
+ @message.delete! # => removes message from all views
98
+
99
+ @message.reply!(body: 'awesome', subject: 'adjusted subject') # => replies to sender. only :body is really needed
100
+
101
+ # With conversation:
102
+ @conversation = Discuss::Conversation.new(@message, user) # => user defaults to message.user if not passed through
103
+ @conversation.all # => shows all the messages, owned or not by the user
104
+ @conversation.for_user # => shows only the messages the user owns
105
+ @conversation.trash_conversation! # => trashes messages in the conversation that the user owns
106
+ ```
107
+
108
+ ## User class
109
+
110
+ The User class has the following method:
111
+
112
+ ```
113
+ def to_s
114
+ full_name
115
+ end
116
+ ```
117
+
118
+ In the gem, these two methods rely on having `first_name`, `last_name` attributes.
119
+ But you can override either method with your implementation.
120
+
121
+ If you wish to actually send out an email, then the User class will also need an `email`.
122
+
123
+ ## Configuring views
124
+
125
+ Since Discuss is an engine, all its views are packaged inside the gem. These views will help you get started.
126
+
127
+ If you wish to customise the views, you just need to invoke the following generator, and it will copy all views to your application:
128
+
129
+ ```shell
130
+ rails generate discuss:views
131
+ ```
132
+
133
+ ## Running the tests
134
+
135
+ ```shell
136
+ rake db:create && rake db:migrate
137
+ rake db:migrate RAILS_ENV=test
138
+ rake test
139
+ ```
140
+
141
+ ## TODO
142
+
143
+ * Use locale yml files for the flash messages
144
+ * Review the helper methods on User
145
+ * Chosen recipients field: ajax request to search for users, and display users by name or email (incase name is missing)
146
+ * Markdown styling for message body
147
+ * Keep draft of unsaved message in local storage
148
+ * Display conversations
149
+ * Mailers
150
+ * Config options to disable or enable mailers
151
+ * Move message delivery and mailers to a background job
152
+
153
+ This project rocks and uses [MIT-LICENSE](MIT-LICENSE).
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Discuss'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,3 @@
1
+ //= require discuss/chosen.jquery
2
+ //= require discuss/discuss
3
+ //= require_tree .
@@ -0,0 +1,1104 @@
1
+ // Chosen, a Select Box Enhancer for jQuery and Prototype
2
+ // by Patrick Filler for Harvest, http://getharvest.com
3
+ //
4
+ // Version 0.9.14
5
+ // Full source at https://github.com/harvesthq/chosen
6
+ // Copyright (c) 2011 Harvest http://getharvest.com
7
+
8
+ // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
9
+ // This file is generated by `cake build`, do not edit it by hand.
10
+ (function() {
11
+ var SelectParser;
12
+
13
+ SelectParser = (function() {
14
+
15
+ function SelectParser() {
16
+ this.options_index = 0;
17
+ this.parsed = [];
18
+ }
19
+
20
+ SelectParser.prototype.add_node = function(child) {
21
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
22
+ return this.add_group(child);
23
+ } else {
24
+ return this.add_option(child);
25
+ }
26
+ };
27
+
28
+ SelectParser.prototype.add_group = function(group) {
29
+ var group_position, option, _i, _len, _ref, _results;
30
+ group_position = this.parsed.length;
31
+ this.parsed.push({
32
+ array_index: group_position,
33
+ group: true,
34
+ label: group.label,
35
+ children: 0,
36
+ disabled: group.disabled
37
+ });
38
+ _ref = group.childNodes;
39
+ _results = [];
40
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
41
+ option = _ref[_i];
42
+ _results.push(this.add_option(option, group_position, group.disabled));
43
+ }
44
+ return _results;
45
+ };
46
+
47
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
48
+ if (option.nodeName.toUpperCase() === "OPTION") {
49
+ if (option.text !== "") {
50
+ if (group_position != null) {
51
+ this.parsed[group_position].children += 1;
52
+ }
53
+ this.parsed.push({
54
+ array_index: this.parsed.length,
55
+ options_index: this.options_index,
56
+ value: option.value,
57
+ text: option.text,
58
+ html: option.innerHTML,
59
+ selected: option.selected,
60
+ disabled: group_disabled === true ? group_disabled : option.disabled,
61
+ group_array_index: group_position,
62
+ classes: option.className,
63
+ style: option.style.cssText
64
+ });
65
+ } else {
66
+ this.parsed.push({
67
+ array_index: this.parsed.length,
68
+ options_index: this.options_index,
69
+ empty: true
70
+ });
71
+ }
72
+ return this.options_index += 1;
73
+ }
74
+ };
75
+
76
+ return SelectParser;
77
+
78
+ })();
79
+
80
+ SelectParser.select_to_array = function(select) {
81
+ var child, parser, _i, _len, _ref;
82
+ parser = new SelectParser();
83
+ _ref = select.childNodes;
84
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
85
+ child = _ref[_i];
86
+ parser.add_node(child);
87
+ }
88
+ return parser.parsed;
89
+ };
90
+
91
+ this.SelectParser = SelectParser;
92
+
93
+ }).call(this);
94
+
95
+ /*
96
+ Chosen source: generate output using 'cake build'
97
+ Copyright (c) 2011 by Harvest
98
+ */
99
+
100
+
101
+ (function() {
102
+ var AbstractChosen, root;
103
+
104
+ root = this;
105
+
106
+ AbstractChosen = (function() {
107
+
108
+ function AbstractChosen(form_field, options) {
109
+ this.form_field = form_field;
110
+ this.options = options != null ? options : {};
111
+ if (!AbstractChosen.browser_is_supported()) {
112
+ return;
113
+ }
114
+ this.is_multiple = this.form_field.multiple;
115
+ this.set_default_text();
116
+ this.set_default_values();
117
+ this.setup();
118
+ this.set_up_html();
119
+ this.register_observers();
120
+ this.finish_setup();
121
+ }
122
+
123
+ AbstractChosen.prototype.set_default_values = function() {
124
+ var _this = this;
125
+ this.click_test_action = function(evt) {
126
+ return _this.test_active_click(evt);
127
+ };
128
+ this.activate_action = function(evt) {
129
+ return _this.activate_field(evt);
130
+ };
131
+ this.active_field = false;
132
+ this.mouse_on_container = false;
133
+ this.results_showing = false;
134
+ this.result_highlighted = null;
135
+ this.result_single_selected = null;
136
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
137
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
138
+ this.disable_search = this.options.disable_search || false;
139
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
140
+ this.search_contains = this.options.search_contains || false;
141
+ this.choices = 0;
142
+ this.single_backstroke_delete = this.options.single_backstroke_delete || false;
143
+ this.max_selected_options = this.options.max_selected_options || Infinity;
144
+ return this.inherit_select_classes = this.options.inherit_select_classes || false;
145
+ };
146
+
147
+ AbstractChosen.prototype.set_default_text = function() {
148
+ if (this.form_field.getAttribute("data-placeholder")) {
149
+ this.default_text = this.form_field.getAttribute("data-placeholder");
150
+ } else if (this.is_multiple) {
151
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
152
+ } else {
153
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
154
+ }
155
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
156
+ };
157
+
158
+ AbstractChosen.prototype.mouse_enter = function() {
159
+ return this.mouse_on_container = true;
160
+ };
161
+
162
+ AbstractChosen.prototype.mouse_leave = function() {
163
+ return this.mouse_on_container = false;
164
+ };
165
+
166
+ AbstractChosen.prototype.input_focus = function(evt) {
167
+ var _this = this;
168
+ if (this.is_multiple) {
169
+ if (!this.active_field) {
170
+ return setTimeout((function() {
171
+ return _this.container_mousedown();
172
+ }), 50);
173
+ }
174
+ } else {
175
+ if (!this.active_field) {
176
+ return this.activate_field();
177
+ }
178
+ }
179
+ };
180
+
181
+ AbstractChosen.prototype.input_blur = function(evt) {
182
+ var _this = this;
183
+ if (!this.mouse_on_container) {
184
+ this.active_field = false;
185
+ return setTimeout((function() {
186
+ return _this.blur_test();
187
+ }), 100);
188
+ }
189
+ };
190
+
191
+ AbstractChosen.prototype.result_add_option = function(option) {
192
+ var classes, style;
193
+ if (!option.disabled) {
194
+ option.dom_id = this.container_id + "_o_" + option.array_index;
195
+ classes = option.selected && this.is_multiple ? [] : ["active-result"];
196
+ if (option.selected) {
197
+ classes.push("result-selected");
198
+ }
199
+ if (option.group_array_index != null) {
200
+ classes.push("group-option");
201
+ }
202
+ if (option.classes !== "") {
203
+ classes.push(option.classes);
204
+ }
205
+ style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
206
+ return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"' + style + '>' + option.html + '</li>';
207
+ } else {
208
+ return "";
209
+ }
210
+ };
211
+
212
+ AbstractChosen.prototype.results_update_field = function() {
213
+ this.set_default_text();
214
+ if (!this.is_multiple) {
215
+ this.results_reset_cleanup();
216
+ }
217
+ this.result_clear_highlight();
218
+ this.result_single_selected = null;
219
+ return this.results_build();
220
+ };
221
+
222
+ AbstractChosen.prototype.results_toggle = function() {
223
+ if (this.results_showing) {
224
+ return this.results_hide();
225
+ } else {
226
+ return this.results_show();
227
+ }
228
+ };
229
+
230
+ AbstractChosen.prototype.results_search = function(evt) {
231
+ if (this.results_showing) {
232
+ return this.winnow_results();
233
+ } else {
234
+ return this.results_show();
235
+ }
236
+ };
237
+
238
+ AbstractChosen.prototype.choices_click = function(evt) {
239
+ evt.preventDefault();
240
+ if (!this.results_showing) {
241
+ return this.results_show();
242
+ }
243
+ };
244
+
245
+ AbstractChosen.prototype.keyup_checker = function(evt) {
246
+ var stroke, _ref;
247
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
248
+ this.search_field_scale();
249
+ switch (stroke) {
250
+ case 8:
251
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) {
252
+ return this.keydown_backstroke();
253
+ } else if (!this.pending_backstroke) {
254
+ this.result_clear_highlight();
255
+ return this.results_search();
256
+ }
257
+ break;
258
+ case 13:
259
+ evt.preventDefault();
260
+ if (this.results_showing) {
261
+ return this.result_select(evt);
262
+ }
263
+ break;
264
+ case 27:
265
+ if (this.results_showing) {
266
+ this.results_hide();
267
+ }
268
+ return true;
269
+ case 9:
270
+ case 38:
271
+ case 40:
272
+ case 16:
273
+ case 91:
274
+ case 17:
275
+ break;
276
+ default:
277
+ return this.results_search();
278
+ }
279
+ };
280
+
281
+ AbstractChosen.prototype.generate_field_id = function() {
282
+ var new_id;
283
+ new_id = this.generate_random_id();
284
+ this.form_field.id = new_id;
285
+ return new_id;
286
+ };
287
+
288
+ AbstractChosen.prototype.generate_random_char = function() {
289
+ var chars, newchar, rand;
290
+ chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
291
+ rand = Math.floor(Math.random() * chars.length);
292
+ return newchar = chars.substring(rand, rand + 1);
293
+ };
294
+
295
+ AbstractChosen.prototype.container_width = function() {
296
+ var width;
297
+ if (this.options.width != null) {
298
+ return this.options.width;
299
+ }
300
+ width = window.getComputedStyle != null ? parseFloat(window.getComputedStyle(this.form_field).getPropertyValue('width')) : (typeof jQuery !== "undefined" && jQuery !== null) && (this.form_field_jq != null) ? this.form_field_jq.outerWidth() : this.form_field.getWidth();
301
+ return width + "px";
302
+ };
303
+
304
+ AbstractChosen.browser_is_supported = function() {
305
+ var _ref;
306
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
307
+ return (null !== (_ref = document.documentMode) && _ref >= 8);
308
+ }
309
+ return true;
310
+ };
311
+
312
+ AbstractChosen.default_multiple_text = "Select Some Options";
313
+
314
+ AbstractChosen.default_single_text = "Select an Option";
315
+
316
+ AbstractChosen.default_no_result_text = "No results match";
317
+
318
+ return AbstractChosen;
319
+
320
+ })();
321
+
322
+ root.AbstractChosen = AbstractChosen;
323
+
324
+ }).call(this);
325
+
326
+ /*
327
+ Chosen source: generate output using 'cake build'
328
+ Copyright (c) 2011 by Harvest
329
+ */
330
+
331
+
332
+ (function() {
333
+ var $, Chosen, root,
334
+ __hasProp = {}.hasOwnProperty,
335
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
336
+
337
+ root = this;
338
+
339
+ $ = jQuery;
340
+
341
+ $.fn.extend({
342
+ chosen: function(options) {
343
+ if (!AbstractChosen.browser_is_supported()) {
344
+ return this;
345
+ }
346
+ return this.each(function(input_field) {
347
+ var $this;
348
+ $this = $(this);
349
+ if (!$this.hasClass("chzn-done")) {
350
+ return $this.data('chosen', new Chosen(this, options));
351
+ }
352
+ });
353
+ }
354
+ });
355
+
356
+ Chosen = (function(_super) {
357
+
358
+ __extends(Chosen, _super);
359
+
360
+ function Chosen() {
361
+ return Chosen.__super__.constructor.apply(this, arguments);
362
+ }
363
+
364
+ Chosen.prototype.setup = function() {
365
+ this.form_field_jq = $(this.form_field);
366
+ this.current_selectedIndex = this.form_field.selectedIndex;
367
+ return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl");
368
+ };
369
+
370
+ Chosen.prototype.finish_setup = function() {
371
+ return this.form_field_jq.addClass("chzn-done");
372
+ };
373
+
374
+ Chosen.prototype.set_up_html = function() {
375
+ var container_classes, container_props;
376
+ this.container_id = this.form_field.id.length ? this.form_field.id.replace(/[^\w]/g, '_') : this.generate_field_id();
377
+ this.container_id += "_chzn";
378
+ container_classes = ["chzn-container"];
379
+ container_classes.push("chzn-container-" + (this.is_multiple ? "multi" : "single"));
380
+ if (this.inherit_select_classes && this.form_field.className) {
381
+ container_classes.push(this.form_field.className);
382
+ }
383
+ if (this.is_rtl) {
384
+ container_classes.push("chzn-rtl");
385
+ }
386
+ container_props = {
387
+ 'id': this.container_id,
388
+ 'class': container_classes.join(' '),
389
+ 'style': "width: " + (this.container_width()) + ";",
390
+ 'title': this.form_field.title
391
+ };
392
+ this.container = $("<div />", container_props);
393
+ if (this.is_multiple) {
394
+ this.container.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop"><ul class="chzn-results"></ul></div>');
395
+ } else {
396
+ this.container.html('<a href="javascript:void(0)" class="chzn-single chzn-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chzn-drop"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>');
397
+ }
398
+ this.form_field_jq.hide().after(this.container);
399
+ this.dropdown = this.container.find('div.chzn-drop').first();
400
+ this.search_field = this.container.find('input').first();
401
+ this.search_results = this.container.find('ul.chzn-results').first();
402
+ this.search_field_scale();
403
+ this.search_no_results = this.container.find('li.no-results').first();
404
+ if (this.is_multiple) {
405
+ this.search_choices = this.container.find('ul.chzn-choices').first();
406
+ this.search_container = this.container.find('li.search-field').first();
407
+ } else {
408
+ this.search_container = this.container.find('div.chzn-search').first();
409
+ this.selected_item = this.container.find('.chzn-single').first();
410
+ }
411
+ this.results_build();
412
+ this.set_tab_index();
413
+ this.set_label_behavior();
414
+ return this.form_field_jq.trigger("liszt:ready", {
415
+ chosen: this
416
+ });
417
+ };
418
+
419
+ Chosen.prototype.register_observers = function() {
420
+ var _this = this;
421
+ this.container.mousedown(function(evt) {
422
+ _this.container_mousedown(evt);
423
+ });
424
+ this.container.mouseup(function(evt) {
425
+ _this.container_mouseup(evt);
426
+ });
427
+ this.container.mouseenter(function(evt) {
428
+ _this.mouse_enter(evt);
429
+ });
430
+ this.container.mouseleave(function(evt) {
431
+ _this.mouse_leave(evt);
432
+ });
433
+ this.search_results.mouseup(function(evt) {
434
+ _this.search_results_mouseup(evt);
435
+ });
436
+ this.search_results.mouseover(function(evt) {
437
+ _this.search_results_mouseover(evt);
438
+ });
439
+ this.search_results.mouseout(function(evt) {
440
+ _this.search_results_mouseout(evt);
441
+ });
442
+ this.search_results.bind('mousewheel DOMMouseScroll', function(evt) {
443
+ _this.search_results_mousewheel(evt);
444
+ });
445
+ this.form_field_jq.bind("liszt:updated", function(evt) {
446
+ _this.results_update_field(evt);
447
+ });
448
+ this.form_field_jq.bind("liszt:activate", function(evt) {
449
+ _this.activate_field(evt);
450
+ });
451
+ this.form_field_jq.bind("liszt:open", function(evt) {
452
+ _this.container_mousedown(evt);
453
+ });
454
+ this.search_field.blur(function(evt) {
455
+ _this.input_blur(evt);
456
+ });
457
+ this.search_field.keyup(function(evt) {
458
+ _this.keyup_checker(evt);
459
+ });
460
+ this.search_field.keydown(function(evt) {
461
+ _this.keydown_checker(evt);
462
+ });
463
+ this.search_field.focus(function(evt) {
464
+ _this.input_focus(evt);
465
+ });
466
+ if (this.is_multiple) {
467
+ return this.search_choices.click(function(evt) {
468
+ _this.choices_click(evt);
469
+ });
470
+ } else {
471
+ return this.container.click(function(evt) {
472
+ evt.preventDefault();
473
+ });
474
+ }
475
+ };
476
+
477
+ Chosen.prototype.search_field_disabled = function() {
478
+ this.is_disabled = this.form_field_jq[0].disabled;
479
+ if (this.is_disabled) {
480
+ this.container.addClass('chzn-disabled');
481
+ this.search_field[0].disabled = true;
482
+ if (!this.is_multiple) {
483
+ this.selected_item.unbind("focus", this.activate_action);
484
+ }
485
+ return this.close_field();
486
+ } else {
487
+ this.container.removeClass('chzn-disabled');
488
+ this.search_field[0].disabled = false;
489
+ if (!this.is_multiple) {
490
+ return this.selected_item.bind("focus", this.activate_action);
491
+ }
492
+ }
493
+ };
494
+
495
+ Chosen.prototype.container_mousedown = function(evt) {
496
+ if (!this.is_disabled) {
497
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
498
+ evt.preventDefault();
499
+ }
500
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
501
+ if (!this.active_field) {
502
+ if (this.is_multiple) {
503
+ this.search_field.val("");
504
+ }
505
+ $(document).click(this.click_test_action);
506
+ this.results_show();
507
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chzn-single").length)) {
508
+ evt.preventDefault();
509
+ this.results_toggle();
510
+ }
511
+ return this.activate_field();
512
+ }
513
+ }
514
+ };
515
+
516
+ Chosen.prototype.container_mouseup = function(evt) {
517
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
518
+ return this.results_reset(evt);
519
+ }
520
+ };
521
+
522
+ Chosen.prototype.search_results_mousewheel = function(evt) {
523
+ var delta, _ref, _ref1;
524
+ delta = -((_ref = evt.originalEvent) != null ? _ref.wheelDelta : void 0) || ((_ref1 = evt.originialEvent) != null ? _ref1.detail : void 0);
525
+ if (delta != null) {
526
+ evt.preventDefault();
527
+ if (evt.type === 'DOMMouseScroll') {
528
+ delta = delta * 40;
529
+ }
530
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
531
+ }
532
+ };
533
+
534
+ Chosen.prototype.blur_test = function(evt) {
535
+ if (!this.active_field && this.container.hasClass("chzn-container-active")) {
536
+ return this.close_field();
537
+ }
538
+ };
539
+
540
+ Chosen.prototype.close_field = function() {
541
+ $(document).unbind("click", this.click_test_action);
542
+ this.active_field = false;
543
+ this.results_hide();
544
+ this.container.removeClass("chzn-container-active");
545
+ this.winnow_results_clear();
546
+ this.clear_backstroke();
547
+ this.show_search_field_default();
548
+ return this.search_field_scale();
549
+ };
550
+
551
+ Chosen.prototype.activate_field = function() {
552
+ this.container.addClass("chzn-container-active");
553
+ this.active_field = true;
554
+ this.search_field.val(this.search_field.val());
555
+ return this.search_field.focus();
556
+ };
557
+
558
+ Chosen.prototype.test_active_click = function(evt) {
559
+ if ($(evt.target).parents('#' + this.container_id).length) {
560
+ return this.active_field = true;
561
+ } else {
562
+ return this.close_field();
563
+ }
564
+ };
565
+
566
+ Chosen.prototype.results_build = function() {
567
+ var content, data, _i, _len, _ref;
568
+ this.parsing = true;
569
+ this.results_data = root.SelectParser.select_to_array(this.form_field);
570
+ if (this.is_multiple && this.choices > 0) {
571
+ this.search_choices.find("li.search-choice").remove();
572
+ this.choices = 0;
573
+ } else if (!this.is_multiple) {
574
+ this.selected_item.addClass("chzn-default").find("span").text(this.default_text);
575
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
576
+ this.container.addClass("chzn-container-single-nosearch");
577
+ } else {
578
+ this.container.removeClass("chzn-container-single-nosearch");
579
+ }
580
+ }
581
+ content = '';
582
+ _ref = this.results_data;
583
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
584
+ data = _ref[_i];
585
+ if (data.group) {
586
+ content += this.result_add_group(data);
587
+ } else if (!data.empty) {
588
+ content += this.result_add_option(data);
589
+ if (data.selected && this.is_multiple) {
590
+ this.choice_build(data);
591
+ } else if (data.selected && !this.is_multiple) {
592
+ this.selected_item.removeClass("chzn-default").find("span").text(data.text);
593
+ if (this.allow_single_deselect) {
594
+ this.single_deselect_control_build();
595
+ }
596
+ }
597
+ }
598
+ }
599
+ this.search_field_disabled();
600
+ this.show_search_field_default();
601
+ this.search_field_scale();
602
+ this.search_results.html(content);
603
+ return this.parsing = false;
604
+ };
605
+
606
+ Chosen.prototype.result_add_group = function(group) {
607
+ if (!group.disabled) {
608
+ group.dom_id = this.container_id + "_g_" + group.array_index;
609
+ return '<li id="' + group.dom_id + '" class="group-result">' + $("<div />").text(group.label).html() + '</li>';
610
+ } else {
611
+ return "";
612
+ }
613
+ };
614
+
615
+ Chosen.prototype.result_do_highlight = function(el) {
616
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
617
+ if (el.length) {
618
+ this.result_clear_highlight();
619
+ this.result_highlight = el;
620
+ this.result_highlight.addClass("highlighted");
621
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
622
+ visible_top = this.search_results.scrollTop();
623
+ visible_bottom = maxHeight + visible_top;
624
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
625
+ high_bottom = high_top + this.result_highlight.outerHeight();
626
+ if (high_bottom >= visible_bottom) {
627
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
628
+ } else if (high_top < visible_top) {
629
+ return this.search_results.scrollTop(high_top);
630
+ }
631
+ }
632
+ };
633
+
634
+ Chosen.prototype.result_clear_highlight = function() {
635
+ if (this.result_highlight) {
636
+ this.result_highlight.removeClass("highlighted");
637
+ }
638
+ return this.result_highlight = null;
639
+ };
640
+
641
+ Chosen.prototype.results_show = function() {
642
+ if (this.result_single_selected != null) {
643
+ this.result_do_highlight(this.result_single_selected);
644
+ } else if (this.is_multiple && this.max_selected_options <= this.choices) {
645
+ this.form_field_jq.trigger("liszt:maxselected", {
646
+ chosen: this
647
+ });
648
+ return false;
649
+ }
650
+ this.container.addClass("chzn-with-drop");
651
+ this.form_field_jq.trigger("liszt:showing_dropdown", {
652
+ chosen: this
653
+ });
654
+ this.results_showing = true;
655
+ this.search_field.focus();
656
+ this.search_field.val(this.search_field.val());
657
+ return this.winnow_results();
658
+ };
659
+
660
+ Chosen.prototype.results_hide = function() {
661
+ this.result_clear_highlight();
662
+ this.container.removeClass("chzn-with-drop");
663
+ this.form_field_jq.trigger("liszt:hiding_dropdown", {
664
+ chosen: this
665
+ });
666
+ return this.results_showing = false;
667
+ };
668
+
669
+ Chosen.prototype.set_tab_index = function(el) {
670
+ var ti;
671
+ if (this.form_field_jq.attr("tabindex")) {
672
+ ti = this.form_field_jq.attr("tabindex");
673
+ this.form_field_jq.attr("tabindex", -1);
674
+ return this.search_field.attr("tabindex", ti);
675
+ }
676
+ };
677
+
678
+ Chosen.prototype.set_label_behavior = function() {
679
+ var _this = this;
680
+ this.form_field_label = this.form_field_jq.parents("label");
681
+ if (!this.form_field_label.length && this.form_field.id.length) {
682
+ this.form_field_label = $("label[for=" + this.form_field.id + "]");
683
+ }
684
+ if (this.form_field_label.length > 0) {
685
+ return this.form_field_label.click(function(evt) {
686
+ if (_this.is_multiple) {
687
+ return _this.container_mousedown(evt);
688
+ } else {
689
+ return _this.activate_field();
690
+ }
691
+ });
692
+ }
693
+ };
694
+
695
+ Chosen.prototype.show_search_field_default = function() {
696
+ if (this.is_multiple && this.choices < 1 && !this.active_field) {
697
+ this.search_field.val(this.default_text);
698
+ return this.search_field.addClass("default");
699
+ } else {
700
+ this.search_field.val("");
701
+ return this.search_field.removeClass("default");
702
+ }
703
+ };
704
+
705
+ Chosen.prototype.search_results_mouseup = function(evt) {
706
+ var target;
707
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
708
+ if (target.length) {
709
+ this.result_highlight = target;
710
+ this.result_select(evt);
711
+ return this.search_field.focus();
712
+ }
713
+ };
714
+
715
+ Chosen.prototype.search_results_mouseover = function(evt) {
716
+ var target;
717
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
718
+ if (target) {
719
+ return this.result_do_highlight(target);
720
+ }
721
+ };
722
+
723
+ Chosen.prototype.search_results_mouseout = function(evt) {
724
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
725
+ return this.result_clear_highlight();
726
+ }
727
+ };
728
+
729
+ Chosen.prototype.choice_build = function(item) {
730
+ var choice_id, html, link,
731
+ _this = this;
732
+ if (this.is_multiple && this.max_selected_options <= this.choices) {
733
+ this.form_field_jq.trigger("liszt:maxselected", {
734
+ chosen: this
735
+ });
736
+ return false;
737
+ }
738
+ choice_id = this.container_id + "_c_" + item.array_index;
739
+ this.choices += 1;
740
+ if (item.disabled) {
741
+ html = '<li class="search-choice search-choice-disabled" id="' + choice_id + '"><span>' + item.html + '</span></li>';
742
+ } else {
743
+ html = '<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>';
744
+ }
745
+ this.search_container.before(html);
746
+ link = $('#' + choice_id).find("a").first();
747
+ return link.click(function(evt) {
748
+ return _this.choice_destroy_link_click(evt);
749
+ });
750
+ };
751
+
752
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
753
+ evt.preventDefault();
754
+ evt.stopPropagation();
755
+ if (!this.is_disabled) {
756
+ return this.choice_destroy($(evt.target));
757
+ }
758
+ };
759
+
760
+ Chosen.prototype.choice_destroy = function(link) {
761
+ if (this.result_deselect(link.attr("rel"))) {
762
+ this.choices -= 1;
763
+ this.show_search_field_default();
764
+ if (this.is_multiple && this.choices > 0 && this.search_field.val().length < 1) {
765
+ this.results_hide();
766
+ }
767
+ link.parents('li').first().remove();
768
+ return this.search_field_scale();
769
+ }
770
+ };
771
+
772
+ Chosen.prototype.results_reset = function() {
773
+ this.form_field.options[0].selected = true;
774
+ this.selected_item.find("span").text(this.default_text);
775
+ if (!this.is_multiple) {
776
+ this.selected_item.addClass("chzn-default");
777
+ }
778
+ this.show_search_field_default();
779
+ this.results_reset_cleanup();
780
+ this.form_field_jq.trigger("change");
781
+ if (this.active_field) {
782
+ return this.results_hide();
783
+ }
784
+ };
785
+
786
+ Chosen.prototype.results_reset_cleanup = function() {
787
+ this.current_selectedIndex = this.form_field.selectedIndex;
788
+ return this.selected_item.find("abbr").remove();
789
+ };
790
+
791
+ Chosen.prototype.result_select = function(evt) {
792
+ var high, high_id, item, position;
793
+ if (this.result_highlight) {
794
+ high = this.result_highlight;
795
+ high_id = high.attr("id");
796
+ this.result_clear_highlight();
797
+ if (this.is_multiple) {
798
+ this.result_deactivate(high);
799
+ } else {
800
+ this.search_results.find(".result-selected").removeClass("result-selected");
801
+ this.result_single_selected = high;
802
+ this.selected_item.removeClass("chzn-default");
803
+ }
804
+ high.addClass("result-selected");
805
+ position = high_id.substr(high_id.lastIndexOf("_") + 1);
806
+ item = this.results_data[position];
807
+ item.selected = true;
808
+ this.form_field.options[item.options_index].selected = true;
809
+ if (this.is_multiple) {
810
+ this.choice_build(item);
811
+ } else {
812
+ this.selected_item.find("span").first().text(item.text);
813
+ if (this.allow_single_deselect) {
814
+ this.single_deselect_control_build();
815
+ }
816
+ }
817
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
818
+ this.results_hide();
819
+ }
820
+ this.search_field.val("");
821
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
822
+ this.form_field_jq.trigger("change", {
823
+ 'selected': this.form_field.options[item.options_index].value
824
+ });
825
+ }
826
+ this.current_selectedIndex = this.form_field.selectedIndex;
827
+ return this.search_field_scale();
828
+ }
829
+ };
830
+
831
+ Chosen.prototype.result_activate = function(el) {
832
+ return el.addClass("active-result");
833
+ };
834
+
835
+ Chosen.prototype.result_deactivate = function(el) {
836
+ return el.removeClass("active-result");
837
+ };
838
+
839
+ Chosen.prototype.result_deselect = function(pos) {
840
+ var result, result_data;
841
+ result_data = this.results_data[pos];
842
+ if (!this.form_field.options[result_data.options_index].disabled) {
843
+ result_data.selected = false;
844
+ this.form_field.options[result_data.options_index].selected = false;
845
+ result = $("#" + this.container_id + "_o_" + pos);
846
+ result.removeClass("result-selected").addClass("active-result").show();
847
+ this.result_clear_highlight();
848
+ this.winnow_results();
849
+ this.form_field_jq.trigger("change", {
850
+ deselected: this.form_field.options[result_data.options_index].value
851
+ });
852
+ this.search_field_scale();
853
+ return true;
854
+ } else {
855
+ return false;
856
+ }
857
+ };
858
+
859
+ Chosen.prototype.single_deselect_control_build = function() {
860
+ if (this.allow_single_deselect && this.selected_item.find("abbr").length < 1) {
861
+ return this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
862
+ }
863
+ };
864
+
865
+ Chosen.prototype.winnow_results = function() {
866
+ var found, option, part, parts, regex, regexAnchor, result, result_id, results, searchText, startpos, text, zregex, _i, _j, _len, _len1, _ref;
867
+ this.no_results_clear();
868
+ results = 0;
869
+ searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
870
+ regexAnchor = this.search_contains ? "" : "^";
871
+ regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
872
+ zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
873
+ _ref = this.results_data;
874
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
875
+ option = _ref[_i];
876
+ if (!option.disabled && !option.empty) {
877
+ if (option.group) {
878
+ $('#' + option.dom_id).css('display', 'none');
879
+ } else if (!(this.is_multiple && option.selected)) {
880
+ found = false;
881
+ result_id = option.dom_id;
882
+ result = $("#" + result_id);
883
+ if (regex.test(option.html)) {
884
+ found = true;
885
+ results += 1;
886
+ } else if (this.enable_split_word_search && (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0)) {
887
+ parts = option.html.replace(/\[|\]/g, "").split(" ");
888
+ if (parts.length) {
889
+ for (_j = 0, _len1 = parts.length; _j < _len1; _j++) {
890
+ part = parts[_j];
891
+ if (regex.test(part)) {
892
+ found = true;
893
+ results += 1;
894
+ }
895
+ }
896
+ }
897
+ }
898
+ if (found) {
899
+ if (searchText.length) {
900
+ startpos = option.html.search(zregex);
901
+ text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length);
902
+ text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
903
+ } else {
904
+ text = option.html;
905
+ }
906
+ result.html(text);
907
+ this.result_activate(result);
908
+ if (option.group_array_index != null) {
909
+ $("#" + this.results_data[option.group_array_index].dom_id).css('display', 'list-item');
910
+ }
911
+ } else {
912
+ if (this.result_highlight && result_id === this.result_highlight.attr('id')) {
913
+ this.result_clear_highlight();
914
+ }
915
+ this.result_deactivate(result);
916
+ }
917
+ }
918
+ }
919
+ }
920
+ if (results < 1 && searchText.length) {
921
+ return this.no_results(searchText);
922
+ } else {
923
+ return this.winnow_results_set_highlight();
924
+ }
925
+ };
926
+
927
+ Chosen.prototype.winnow_results_clear = function() {
928
+ var li, lis, _i, _len, _results;
929
+ this.search_field.val("");
930
+ lis = this.search_results.find("li");
931
+ _results = [];
932
+ for (_i = 0, _len = lis.length; _i < _len; _i++) {
933
+ li = lis[_i];
934
+ li = $(li);
935
+ if (li.hasClass("group-result")) {
936
+ _results.push(li.css('display', 'auto'));
937
+ } else if (!this.is_multiple || !li.hasClass("result-selected")) {
938
+ _results.push(this.result_activate(li));
939
+ } else {
940
+ _results.push(void 0);
941
+ }
942
+ }
943
+ return _results;
944
+ };
945
+
946
+ Chosen.prototype.winnow_results_set_highlight = function() {
947
+ var do_high, selected_results;
948
+ if (!this.result_highlight) {
949
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
950
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
951
+ if (do_high != null) {
952
+ return this.result_do_highlight(do_high);
953
+ }
954
+ }
955
+ };
956
+
957
+ Chosen.prototype.no_results = function(terms) {
958
+ var no_results_html;
959
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
960
+ no_results_html.find("span").first().html(terms);
961
+ return this.search_results.append(no_results_html);
962
+ };
963
+
964
+ Chosen.prototype.no_results_clear = function() {
965
+ return this.search_results.find(".no-results").remove();
966
+ };
967
+
968
+ Chosen.prototype.keydown_arrow = function() {
969
+ var first_active, next_sib;
970
+ if (!this.result_highlight) {
971
+ first_active = this.search_results.find("li.active-result").first();
972
+ if (first_active) {
973
+ this.result_do_highlight($(first_active));
974
+ }
975
+ } else if (this.results_showing) {
976
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
977
+ if (next_sib) {
978
+ this.result_do_highlight(next_sib);
979
+ }
980
+ }
981
+ if (!this.results_showing) {
982
+ return this.results_show();
983
+ }
984
+ };
985
+
986
+ Chosen.prototype.keyup_arrow = function() {
987
+ var prev_sibs;
988
+ if (!this.results_showing && !this.is_multiple) {
989
+ return this.results_show();
990
+ } else if (this.result_highlight) {
991
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
992
+ if (prev_sibs.length) {
993
+ return this.result_do_highlight(prev_sibs.first());
994
+ } else {
995
+ if (this.choices > 0) {
996
+ this.results_hide();
997
+ }
998
+ return this.result_clear_highlight();
999
+ }
1000
+ }
1001
+ };
1002
+
1003
+ Chosen.prototype.keydown_backstroke = function() {
1004
+ var next_available_destroy;
1005
+ if (this.pending_backstroke) {
1006
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1007
+ return this.clear_backstroke();
1008
+ } else {
1009
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1010
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1011
+ this.pending_backstroke = next_available_destroy;
1012
+ if (this.single_backstroke_delete) {
1013
+ return this.keydown_backstroke();
1014
+ } else {
1015
+ return this.pending_backstroke.addClass("search-choice-focus");
1016
+ }
1017
+ }
1018
+ }
1019
+ };
1020
+
1021
+ Chosen.prototype.clear_backstroke = function() {
1022
+ if (this.pending_backstroke) {
1023
+ this.pending_backstroke.removeClass("search-choice-focus");
1024
+ }
1025
+ return this.pending_backstroke = null;
1026
+ };
1027
+
1028
+ Chosen.prototype.keydown_checker = function(evt) {
1029
+ var stroke, _ref;
1030
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
1031
+ this.search_field_scale();
1032
+ if (stroke !== 8 && this.pending_backstroke) {
1033
+ this.clear_backstroke();
1034
+ }
1035
+ switch (stroke) {
1036
+ case 8:
1037
+ this.backstroke_length = this.search_field.val().length;
1038
+ break;
1039
+ case 9:
1040
+ if (this.results_showing && !this.is_multiple) {
1041
+ this.result_select(evt);
1042
+ }
1043
+ this.mouse_on_container = false;
1044
+ break;
1045
+ case 13:
1046
+ evt.preventDefault();
1047
+ break;
1048
+ case 38:
1049
+ evt.preventDefault();
1050
+ this.keyup_arrow();
1051
+ break;
1052
+ case 40:
1053
+ this.keydown_arrow();
1054
+ break;
1055
+ }
1056
+ };
1057
+
1058
+ Chosen.prototype.search_field_scale = function() {
1059
+ var div, h, style, style_block, styles, w, _i, _len;
1060
+ if (this.is_multiple) {
1061
+ h = 0;
1062
+ w = 0;
1063
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1064
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1065
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
1066
+ style = styles[_i];
1067
+ style_block += style + ":" + this.search_field.css(style) + ";";
1068
+ }
1069
+ div = $('<div />', {
1070
+ 'style': style_block
1071
+ });
1072
+ div.text(this.search_field.val());
1073
+ $('body').append(div);
1074
+ w = div.width() + 25;
1075
+ div.remove();
1076
+ if (!this.f_width) {
1077
+ this.f_width = this.container.outerWidth();
1078
+ }
1079
+ if (w > this.f_width - 10) {
1080
+ w = this.f_width - 10;
1081
+ }
1082
+ return this.search_field.css({
1083
+ 'width': w + 'px'
1084
+ });
1085
+ }
1086
+ };
1087
+
1088
+ Chosen.prototype.generate_random_id = function() {
1089
+ var string;
1090
+ string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char();
1091
+ while ($("#" + string).length > 0) {
1092
+ string += this.generate_random_char();
1093
+ }
1094
+ return string;
1095
+ };
1096
+
1097
+ return Chosen;
1098
+
1099
+ })(AbstractChosen);
1100
+
1101
+ root.Chosen = Chosen;
1102
+
1103
+ }).call(this);
1104
+