ack_rocket_cms 0.7.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +19 -0
  7. data/Gemfile +5 -0
  8. data/Gemfile.lock +244 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +74 -0
  11. data/Rakefile +1 -0
  12. data/app/assets/javascripts/head.load.js +707 -0
  13. data/app/assets/javascripts/jquery.placeholder.js +157 -0
  14. data/app/assets/javascripts/rocket_cms.js.coffee +10 -0
  15. data/app/assets/javascripts/rocket_cms/flash.js.coffee +3 -0
  16. data/app/assets/javascripts/rocket_cms/map.js.coffee +22 -0
  17. data/app/assets/stylesheets/rocket_cms.css.sass +6 -0
  18. data/app/assets/stylesheets/rocket_cms/flash.css.sass +66 -0
  19. data/app/assets/stylesheets/rocket_cms/normalize.css.scss +406 -0
  20. data/app/controllers/concerns/no_cache.rb +12 -0
  21. data/app/controllers/concerns/rs_errors.rb +63 -0
  22. data/app/controllers/concerns/rs_menu.rb +45 -0
  23. data/app/controllers/concerns/rs_pages.rb +41 -0
  24. data/app/controllers/contacts_controller.rb +3 -0
  25. data/app/controllers/home_controller.rb +5 -0
  26. data/app/controllers/news_controller.rb +3 -0
  27. data/app/controllers/pages_controller.rb +4 -0
  28. data/app/controllers/search_controller.rb +4 -0
  29. data/app/mailers/contact_mailer.rb +15 -0
  30. data/app/models/concerns/boolean_field.rb +17 -0
  31. data/app/models/concerns/enableable.rb +8 -0
  32. data/app/models/concerns/geocodeable.rb +4 -0
  33. data/app/models/concerns/mappable.rb +95 -0
  34. data/app/models/concerns/seoable.rb +42 -0
  35. data/app/models/concerns/sitemap_data.rb +20 -0
  36. data/app/models/concerns/sort_field.rb +17 -0
  37. data/app/models/concerns/sortable.rb +8 -0
  38. data/app/models/contact_message.rb +11 -0
  39. data/app/models/menu.rb +11 -0
  40. data/app/models/news.rb +10 -0
  41. data/app/models/page.rb +11 -0
  42. data/app/views/blocks/_footer.html.haml +1 -0
  43. data/app/views/contact_mailer/new_message_email.html.haml +16 -0
  44. data/app/views/contacts/index.html.haml +10 -0
  45. data/app/views/contacts/new.html.haml +10 -0
  46. data/app/views/contacts/sent.html.haml +4 -0
  47. data/app/views/errors/_base.html.haml +3 -0
  48. data/app/views/errors/error_403.html.haml +1 -0
  49. data/app/views/errors/error_404.html.haml +1 -0
  50. data/app/views/errors/error_500.html.haml +1 -0
  51. data/app/views/home/index.html.haml +1 -0
  52. data/app/views/layouts/application.html.haml +23 -0
  53. data/app/views/layouts/application.html.slim +24 -0
  54. data/app/views/news/index.html.haml +9 -0
  55. data/app/views/news/show.html.haml +8 -0
  56. data/app/views/pages/show.html.haml +1 -0
  57. data/app/views/rails_admin/main/_check_boxes.html.haml +27 -0
  58. data/app/views/rails_admin/main/_enum_check_boxes.html.haml +5 -0
  59. data/app/views/rails_admin/main/_enum_radio_buttons.html.haml +5 -0
  60. data/app/views/rails_admin/main/_form_raw.html.haml +1 -0
  61. data/app/views/search/index.html.haml +19 -0
  62. data/app/views/shared/_admin_link.html.haml +3 -0
  63. data/app/views/shared/_messages.html.haml +7 -0
  64. data/app/views/shared/_meta.html.haml +6 -0
  65. data/app/views/shared/_obj.html.haml +20 -0
  66. data/app/views/shared/_og.html.haml +4 -0
  67. data/config/locales/en.rocket_admin.yml +6 -0
  68. data/config/locales/en.rs.yml +20 -0
  69. data/config/locales/ru.cancan.yml +4 -0
  70. data/config/locales/ru.devise.yml +65 -0
  71. data/config/locales/ru.kaminari.yml +17 -0
  72. data/config/locales/ru.models.yml +92 -0
  73. data/config/locales/ru.mongoid.yml +450 -0
  74. data/config/locales/ru.rails_admin.yml +148 -0
  75. data/config/locales/ru.rocket_admin.yml +6 -0
  76. data/config/locales/ru.rs.yml +20 -0
  77. data/config/locales/ru.simple_captcha.yml +3 -0
  78. data/config/locales/ru.simple_form.yml +9 -0
  79. data/lib/filename_to_slug.rb +34 -0
  80. data/lib/generators/rocket_cms/ability_generator.rb +15 -0
  81. data/lib/generators/rocket_cms/admin_generator.rb +21 -0
  82. data/lib/generators/rocket_cms/capify_generator.rb +40 -0
  83. data/lib/generators/rocket_cms/layout_generator.rb +15 -0
  84. data/lib/generators/rocket_cms/migration_generator.rb +19 -0
  85. data/lib/generators/rocket_cms/templates/Capfile +17 -0
  86. data/lib/generators/rocket_cms/templates/ability.erb +28 -0
  87. data/lib/generators/rocket_cms/templates/admin.erb +81 -0
  88. data/lib/generators/rocket_cms/templates/deploy.erb +47 -0
  89. data/lib/generators/rocket_cms/templates/dl.erb +30 -0
  90. data/lib/generators/rocket_cms/templates/migration_contact_messages.rb +15 -0
  91. data/lib/generators/rocket_cms/templates/migration_news.rb +21 -0
  92. data/lib/generators/rocket_cms/templates/migration_pages.rb +36 -0
  93. data/lib/generators/rocket_cms/templates/production.erb +8 -0
  94. data/lib/generators/rocket_cms/templates/unicorn.erb +66 -0
  95. data/lib/generators/rocket_cms/utils.rb +22 -0
  96. data/lib/manual_slug.rb +11 -0
  97. data/lib/manual_slug/active_record.rb +32 -0
  98. data/lib/manual_slug/mongoid.rb +36 -0
  99. data/lib/rails_admin/custom_show_in_app.rb +39 -0
  100. data/lib/rocket_cms.rb +88 -0
  101. data/lib/rocket_cms/admin.rb +152 -0
  102. data/lib/rocket_cms/configuration.rb +67 -0
  103. data/lib/rocket_cms/controller.rb +24 -0
  104. data/lib/rocket_cms/controllers/contacts.rb +70 -0
  105. data/lib/rocket_cms/controllers/news.rb +31 -0
  106. data/lib/rocket_cms/controllers/pages.rb +19 -0
  107. data/lib/rocket_cms/controllers/search.rb +45 -0
  108. data/lib/rocket_cms/elastic_search.rb +31 -0
  109. data/lib/rocket_cms/engine.rb +39 -0
  110. data/lib/rocket_cms/migration.rb +31 -0
  111. data/lib/rocket_cms/model.rb +25 -0
  112. data/lib/rocket_cms/models/active_record/contact_message.rb +14 -0
  113. data/lib/rocket_cms/models/active_record/menu.rb +14 -0
  114. data/lib/rocket_cms/models/active_record/news.rb +23 -0
  115. data/lib/rocket_cms/models/active_record/page.rb +17 -0
  116. data/lib/rocket_cms/models/contact_message.rb +27 -0
  117. data/lib/rocket_cms/models/menu.rb +29 -0
  118. data/lib/rocket_cms/models/mongoid/contact_message.rb +20 -0
  119. data/lib/rocket_cms/models/mongoid/menu.rb +12 -0
  120. data/lib/rocket_cms/models/mongoid/news.rb +27 -0
  121. data/lib/rocket_cms/models/mongoid/page.rb +26 -0
  122. data/lib/rocket_cms/models/news.rb +50 -0
  123. data/lib/rocket_cms/models/page.rb +76 -0
  124. data/lib/rocket_cms/patch.rb +58 -0
  125. data/lib/rocket_cms/rails_admin_menu.rb +145 -0
  126. data/lib/rocket_cms/simple_form_patch.rb +12 -0
  127. data/lib/rocket_cms/tasks.rb +13 -0
  128. data/lib/rocket_cms/version.rb +3 -0
  129. data/release.sh +13 -0
  130. data/rocket_cms.gemspec +54 -0
  131. data/template.rb +557 -0
  132. metadata +533 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 71cf0a840e9fc4d90edd0b8e308078414d68d866
4
+ data.tar.gz: 38d6511abca3082f32617f41a1c7a7fe7125a969
5
+ SHA512:
6
+ metadata.gz: ad84e1aae5374151b462a1cb293289219ca036d2974f4bc4a9281f05fa3329249ea217d77d04bcd746353e1127737b31c400b41d969acf6a11ae5cd335fe93ee
7
+ data.tar.gz: 5c06f4eeed839d11ef4d98b076ab62f6b6d8ceb86c1166a746b2df5aa14d5dc2485a7abd4fc74f714b9f602c636f73972075b339133dfea453511bd73a013a24
@@ -0,0 +1,21 @@
1
+ .idea
2
+ .idea/*
3
+
4
+ *.gem
5
+ *.rbc
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ mongoid/Gemfile.lock
21
+ activerecord/Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1 @@
1
+ rocket_cms
@@ -0,0 +1 @@
1
+ 2.2.0
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ services: mongodb
3
+
4
+ notifications:
5
+ email: false
6
+
7
+ rvm:
8
+ - 1.9.3
9
+ - 2.0.0
10
+ - 2.1.0
11
+ - jruby-20mode
12
+
13
+ env:
14
+ - "UPLOADS=paperclip"
15
+ - "UPLOADS=carrierwave"
16
+
17
+ gemfile:
18
+ - gemfiles/mongoid-3.1.gemfile
19
+ - gemfiles/mongoid-4.0.gemfile
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rocket_cms.gemspec
4
+ gemspec
5
+
@@ -0,0 +1,244 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ack_rocket_cms (0.7.2.1)
5
+ addressable
6
+ coffee-rails
7
+ devise
8
+ geocoder
9
+ glebtv-ckeditor
10
+ glebtv-simple_captcha
11
+ jquery-rails
12
+ kaminari
13
+ rails (>= 4.1.0, < 5.0)
14
+ rails_admin
15
+ rails_admin_mongoid_localize_field (~> 0.1.2)
16
+ rails_admin_nested_set
17
+ rails_admin_settings (~> 0.9.0)
18
+ rails_admin_toggleable
19
+ simple-navigation
20
+ simple_form
21
+ sitemap_generator
22
+ smart_excerpt
23
+ stringex
24
+ thor
25
+ turbolinks
26
+ validates_email_format_of
27
+ x-real-ip
28
+
29
+ GEM
30
+ remote: https://rubygems.org/
31
+ specs:
32
+ actionmailer (4.2.0)
33
+ actionpack (= 4.2.0)
34
+ actionview (= 4.2.0)
35
+ activejob (= 4.2.0)
36
+ mail (~> 2.5, >= 2.5.4)
37
+ rails-dom-testing (~> 1.0, >= 1.0.5)
38
+ actionpack (4.2.0)
39
+ actionview (= 4.2.0)
40
+ activesupport (= 4.2.0)
41
+ rack (~> 1.6.0)
42
+ rack-test (~> 0.6.2)
43
+ rails-dom-testing (~> 1.0, >= 1.0.5)
44
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
45
+ actionview (4.2.0)
46
+ activesupport (= 4.2.0)
47
+ builder (~> 3.1)
48
+ erubis (~> 2.7.0)
49
+ rails-dom-testing (~> 1.0, >= 1.0.5)
50
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
51
+ activejob (4.2.0)
52
+ activesupport (= 4.2.0)
53
+ globalid (>= 0.3.0)
54
+ activemodel (4.2.0)
55
+ activesupport (= 4.2.0)
56
+ builder (~> 3.1)
57
+ activerecord (4.2.0)
58
+ activemodel (= 4.2.0)
59
+ activesupport (= 4.2.0)
60
+ arel (~> 6.0)
61
+ activesupport (4.2.0)
62
+ i18n (~> 0.7)
63
+ json (~> 1.7, >= 1.7.7)
64
+ minitest (~> 5.1)
65
+ thread_safe (~> 0.3, >= 0.3.4)
66
+ tzinfo (~> 1.1)
67
+ addressable (2.3.7)
68
+ arel (6.0.0)
69
+ bcrypt (3.1.10)
70
+ bson (2.3.0)
71
+ builder (3.2.2)
72
+ coffee-rails (4.1.0)
73
+ coffee-script (>= 2.2.0)
74
+ railties (>= 4.0.0, < 5.0)
75
+ coffee-script (2.3.0)
76
+ coffee-script-source
77
+ execjs
78
+ coffee-script-source (1.9.0)
79
+ connection_pool (2.1.1)
80
+ devise (3.4.1)
81
+ bcrypt (~> 3.0)
82
+ orm_adapter (~> 0.1)
83
+ railties (>= 3.2.6, < 5)
84
+ responders
85
+ thread_safe (~> 0.1)
86
+ warden (~> 1.2.3)
87
+ erubis (2.7.0)
88
+ execjs (2.3.0)
89
+ font-awesome-rails (4.3.0.0)
90
+ railties (>= 3.2, < 5.0)
91
+ geocoder (1.2.7)
92
+ glebtv-ckeditor (4.4.6)
93
+ mime-types
94
+ orm_adapter (~> 0.5.0)
95
+ rails (~> 4.0)
96
+ glebtv-simple_captcha (0.6.7)
97
+ globalid (0.3.3)
98
+ activesupport (>= 4.1.0)
99
+ haml (4.0.6)
100
+ tilt
101
+ hike (1.2.3)
102
+ htmlentities (4.3.3)
103
+ i18n (0.7.0)
104
+ jquery-rails (4.0.3)
105
+ rails-dom-testing (~> 1.0)
106
+ railties (>= 4.2.0)
107
+ thor (>= 0.14, < 2.0)
108
+ jquery-ui-rails (5.0.3)
109
+ railties (>= 3.2.16)
110
+ json (1.8.2)
111
+ kaminari (0.16.3)
112
+ actionpack (>= 3.0.0)
113
+ activesupport (>= 3.0.0)
114
+ loofah (2.0.1)
115
+ nokogiri (>= 1.5.9)
116
+ mail (2.6.3)
117
+ mime-types (>= 1.16, < 3)
118
+ mime-types (2.4.3)
119
+ mini_portile (0.6.2)
120
+ minitest (5.5.1)
121
+ mongoid (4.0.1)
122
+ activemodel (~> 4.0)
123
+ moped (~> 2.0.0)
124
+ origin (~> 2.1)
125
+ tzinfo (>= 0.3.37)
126
+ moped (2.0.3)
127
+ bson (~> 2.2)
128
+ connection_pool (~> 2.0)
129
+ optionable (~> 0.2.0)
130
+ multi_json (1.10.1)
131
+ nested_form (0.3.2)
132
+ nokogiri (1.6.6.2)
133
+ mini_portile (~> 0.6.0)
134
+ optionable (0.2.0)
135
+ origin (2.1.1)
136
+ orm_adapter (0.5.0)
137
+ rack (1.6.0)
138
+ rack-pjax (0.8.0)
139
+ nokogiri (~> 1.5)
140
+ rack (~> 1.1)
141
+ rack-test (0.6.3)
142
+ rack (>= 1.0)
143
+ rails (4.2.0)
144
+ actionmailer (= 4.2.0)
145
+ actionpack (= 4.2.0)
146
+ actionview (= 4.2.0)
147
+ activejob (= 4.2.0)
148
+ activemodel (= 4.2.0)
149
+ activerecord (= 4.2.0)
150
+ activesupport (= 4.2.0)
151
+ bundler (>= 1.3.0, < 2.0)
152
+ railties (= 4.2.0)
153
+ sprockets-rails
154
+ rails-deprecated_sanitizer (1.0.3)
155
+ activesupport (>= 4.2.0.alpha)
156
+ rails-dom-testing (1.0.5)
157
+ activesupport (>= 4.2.0.beta, < 5.0)
158
+ nokogiri (~> 1.6.0)
159
+ rails-deprecated_sanitizer (>= 1.0.1)
160
+ rails-html-sanitizer (1.0.1)
161
+ loofah (~> 2.0)
162
+ rails_admin (0.6.6)
163
+ builder (~> 3.1)
164
+ coffee-rails (~> 4.0)
165
+ font-awesome-rails (>= 3.0, < 5)
166
+ haml (~> 4.0)
167
+ jquery-rails (>= 3.0, < 5)
168
+ jquery-ui-rails (~> 5.0)
169
+ kaminari (~> 0.14)
170
+ nested_form (~> 0.3)
171
+ rack-pjax (~> 0.7)
172
+ rails (~> 4.0)
173
+ remotipart (~> 1.0)
174
+ safe_yaml (~> 1.0)
175
+ sass-rails (>= 4.0, < 6)
176
+ rails_admin_mongoid_localize_field (0.1.3)
177
+ haml
178
+ mongoid (>= 3.0)
179
+ rails (>= 3.0)
180
+ rails_admin (>= 0.5)
181
+ rails_admin_nested_set (0.4.0)
182
+ rails_admin (~> 0.6.6)
183
+ rails_admin_settings (0.9.1)
184
+ rails_admin_toggleable (0.5.0)
185
+ rails_admin (~> 0.6.6)
186
+ railties (4.2.0)
187
+ actionpack (= 4.2.0)
188
+ activesupport (= 4.2.0)
189
+ rake (>= 0.8.7)
190
+ thor (>= 0.18.1, < 2.0)
191
+ rake (10.4.2)
192
+ remotipart (1.2.1)
193
+ responders (2.1.0)
194
+ railties (>= 4.2.0, < 5)
195
+ safe_yaml (1.0.4)
196
+ sass (3.4.11)
197
+ sass-rails (5.0.1)
198
+ railties (>= 4.0.0, < 5.0)
199
+ sass (~> 3.1)
200
+ sprockets (>= 2.8, < 4.0)
201
+ sprockets-rails (>= 2.0, < 4.0)
202
+ tilt (~> 1.1)
203
+ simple-navigation (3.14.0)
204
+ activesupport (>= 2.3.2)
205
+ simple_form (3.1.0)
206
+ actionpack (~> 4.0)
207
+ activemodel (~> 4.0)
208
+ sitemap_generator (5.0.5)
209
+ builder
210
+ smart_excerpt (0.1.5)
211
+ activesupport
212
+ htmlentities
213
+ sprockets (2.12.3)
214
+ hike (~> 1.2)
215
+ multi_json (~> 1.0)
216
+ rack (~> 1.0)
217
+ tilt (~> 1.1, != 1.3.0)
218
+ sprockets-rails (2.2.4)
219
+ actionpack (>= 3.0)
220
+ activesupport (>= 3.0)
221
+ sprockets (>= 2.8, < 4.0)
222
+ stringex (2.5.2)
223
+ thor (0.19.1)
224
+ thread_safe (0.3.4)
225
+ tilt (1.4.1)
226
+ turbolinks (2.5.3)
227
+ coffee-rails
228
+ tzinfo (1.2.2)
229
+ thread_safe (~> 0.1)
230
+ validates_email_format_of (1.6.2)
231
+ i18n
232
+ warden (1.2.3)
233
+ rack (>= 1.0)
234
+ x-real-ip (0.2.0)
235
+ activesupport
236
+ rack
237
+
238
+ PLATFORMS
239
+ ruby
240
+
241
+ DEPENDENCIES
242
+ ack_rocket_cms!
243
+ bundler
244
+ rake
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 glebtv
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,74 @@
1
+ # RocketCMS
2
+
3
+ rails_admin + mongoid/activerecord + elasticsearch CMS
4
+
5
+ Very opinionated and tuned for our needs.
6
+
7
+ Sorry, no documentation or examples are availiable yet. Stay tuned
8
+
9
+ **Before 1.0 API and class names should be considered unstable and can change at
10
+ any time!**
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'rocket_cms_mongoid', github: "ack43/rocket_cms", branch: :master
17
+
18
+ or:
19
+
20
+ gem 'rocket_cms_activerecord', github: "ack43/rocket_cms", branch: :master
21
+
22
+ *Only PostgreSQL is tested or supported for AR. Others will probably work, but untested.*
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install rocket_cms
31
+
32
+ For activerecord, generate migrations and run them
33
+
34
+ rails g rails_admin_settings:migration
35
+ rails g rocket_cms:migration
36
+ rake db:migrate
37
+
38
+ ## Usage
39
+
40
+ ### Using app generator
41
+
42
+ Make sure you have rails 4.1 installed
43
+
44
+ rails -v
45
+
46
+ If not, uninstall rails and install again
47
+
48
+ gem uninstall rails
49
+ gem install rocket_cms
50
+
51
+ Then, for mongoid:
52
+
53
+ rails new my_app -T -O -m https://raw.github.com/ack43/rocket_cms/master/template.rb
54
+
55
+ for ActiveRecord:
56
+
57
+ rails new my_app -T --database=postgresql -m https://raw.github.com/ack43/rocket_cms/master/template.rb
58
+
59
+ generator creates a new RVM gemset, so after cd'ing to app dir, you should run `bundle install` again if you use rvm.
60
+
61
+ ### Documentation
62
+
63
+ It's basically Mongoid + Rails Admin + some of our common models and controllers, capistrano config, etc.
64
+
65
+ See their documentation for more info
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
74
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,707 @@
1
+ ///#source 1 1 /src/1.0.0/load.js
2
+ /*! head.load - v1.0.3 */
3
+ /*
4
+ * HeadJS The only script in your <HEAD>
5
+ * Author Tero Piirainen (tipiirai)
6
+ * Maintainer Robert Hoffmann (itechnology)
7
+ * License MIT / http://bit.ly/mit-license
8
+ * WebSite http://headjs.com
9
+ */
10
+ (function (win, undefined) {
11
+ "use strict";
12
+
13
+ //#region variables
14
+ var doc = win.document,
15
+ domWaiters = [],
16
+ handlers = {}, // user functions waiting for events
17
+ assets = {}, // loadable items in various states
18
+ isAsync = "async" in doc.createElement("script") || "MozAppearance" in doc.documentElement.style || win.opera,
19
+ isDomReady,
20
+
21
+ /*** public API ***/
22
+ headVar = win.head_conf && win.head_conf.head || "head",
23
+ api = win[headVar] = (win[headVar] || function () { api.ready.apply(null, arguments); }),
24
+
25
+ // states
26
+ PRELOADING = 1,
27
+ PRELOADED = 2,
28
+ LOADING = 3,
29
+ LOADED = 4;
30
+ //#endregion
31
+
32
+ //#region PRIVATE functions
33
+
34
+ //#region Helper functions
35
+ function noop() {
36
+ // does nothing
37
+ }
38
+
39
+ function each(arr, callback) {
40
+ if (!arr) {
41
+ return;
42
+ }
43
+
44
+ // arguments special type
45
+ if (typeof arr === "object") {
46
+ arr = [].slice.call(arr);
47
+ }
48
+
49
+ // do the job
50
+ for (var i = 0, l = arr.length; i < l; i++) {
51
+ callback.call(arr, arr[i], i);
52
+ }
53
+ }
54
+
55
+ /* A must read: http://bonsaiden.github.com/JavaScript-Garden
56
+ ************************************************************/
57
+ function is(type, obj) {
58
+ var clas = Object.prototype.toString.call(obj).slice(8, -1);
59
+ return obj !== undefined && obj !== null && clas === type;
60
+ }
61
+
62
+ function isFunction(item) {
63
+ return is("Function", item);
64
+ }
65
+
66
+ function isArray(item) {
67
+ return is("Array", item);
68
+ }
69
+
70
+ function toLabel(url) {
71
+ ///<summary>Converts a url to a file label</summary>
72
+ var items = url.split("/"),
73
+ name = items[items.length - 1],
74
+ i = name.indexOf("?");
75
+
76
+ return i !== -1 ? name.substring(0, i) : name;
77
+ }
78
+
79
+ // INFO: this look like a "im triggering callbacks all over the place, but only wanna run it one time function" ..should try to make everything work without it if possible
80
+ // INFO: Even better. Look into promises/defered's like jQuery is doing
81
+ function one(callback) {
82
+ ///<summary>Execute a callback only once</summary>
83
+ callback = callback || noop;
84
+
85
+ if (callback._done) {
86
+ return;
87
+ }
88
+
89
+ callback();
90
+ callback._done = 1;
91
+ }
92
+ //#endregion
93
+
94
+ function conditional(test, success, failure, callback) {
95
+ ///<summary>
96
+ /// INFO: use cases:
97
+ /// head.test(condition, null , "file.NOk" , callback);
98
+ /// head.test(condition, "fileOk.js", null , callback);
99
+ /// head.test(condition, "fileOk.js", "file.NOk" , callback);
100
+ /// head.test(condition, "fileOk.js", ["file.NOk", "file.NOk"], callback);
101
+ /// head.test({
102
+ /// test : condition,
103
+ /// success : [{ label1: "file1Ok.js" }, { label2: "file2Ok.js" }],
104
+ /// failure : [{ label1: "file1NOk.js" }, { label2: "file2NOk.js" }],
105
+ /// callback: callback
106
+ /// );
107
+ /// head.test({
108
+ /// test : condition,
109
+ /// success : ["file1Ok.js" , "file2Ok.js"],
110
+ /// failure : ["file1NOk.js", "file2NOk.js"],
111
+ /// callback: callback
112
+ /// );
113
+ ///</summary>
114
+ var obj = (typeof test === "object") ? test : {
115
+ test: test,
116
+ success: !!success ? isArray(success) ? success : [success] : false,
117
+ failure: !!failure ? isArray(failure) ? failure : [failure] : false,
118
+ callback: callback || noop
119
+ };
120
+
121
+ // Test Passed ?
122
+ var passed = !!obj.test;
123
+
124
+ // Do we have a success case
125
+ if (passed && !!obj.success) {
126
+ obj.success.push(obj.callback);
127
+ api.load.apply(null, obj.success);
128
+ }
129
+ // Do we have a fail case
130
+ else if (!passed && !!obj.failure) {
131
+ obj.failure.push(obj.callback);
132
+ api.load.apply(null, obj.failure);
133
+ }
134
+ else {
135
+ callback();
136
+ }
137
+
138
+ return api;
139
+ }
140
+
141
+ function getAsset(item) {
142
+ ///<summary>
143
+ /// Assets are in the form of
144
+ /// {
145
+ /// name : label,
146
+ /// url : url,
147
+ /// state: state
148
+ /// }
149
+ ///</summary>
150
+ var asset = {};
151
+
152
+ if (typeof item === "object") {
153
+ for (var label in item) {
154
+ if (!!item[label]) {
155
+ asset = {
156
+ name: label,
157
+ url : item[label]
158
+ };
159
+ }
160
+ }
161
+ }
162
+ else {
163
+ asset = {
164
+ name: toLabel(item),
165
+ url : item
166
+ };
167
+ }
168
+
169
+ // is the item already existant
170
+ var existing = assets[asset.name];
171
+ if (existing && existing.url === asset.url) {
172
+ return existing;
173
+ }
174
+
175
+ assets[asset.name] = asset;
176
+ return asset;
177
+ }
178
+
179
+ function allLoaded(items) {
180
+ items = items || assets;
181
+
182
+ for (var name in items) {
183
+ if (items.hasOwnProperty(name) && items[name].state !== LOADED) {
184
+ return false;
185
+ }
186
+ }
187
+
188
+ return true;
189
+ }
190
+
191
+ function onPreload(asset) {
192
+ asset.state = PRELOADED;
193
+
194
+ each(asset.onpreload, function (afterPreload) {
195
+ afterPreload.call();
196
+ });
197
+ }
198
+
199
+ function preLoad(asset, callback) {
200
+ if (asset.state === undefined) {
201
+
202
+ asset.state = PRELOADING;
203
+ asset.onpreload = [];
204
+
205
+ loadAsset({ url: asset.url, type: "cache" }, function () {
206
+ onPreload(asset);
207
+ });
208
+ }
209
+ }
210
+
211
+ function apiLoadHack() {
212
+ /// <summary>preload with text/cache hack
213
+ ///
214
+ /// head.load("http://domain.com/file.js","http://domain.com/file.js", callBack)
215
+ /// head.load(["http://domain.com/file.js","http://domain.com/file.js"], callBack)
216
+ /// head.load({ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }, callBack)
217
+ /// head.load([{ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }], callBack)
218
+ /// </summary>
219
+ var args = arguments,
220
+ callback = args[args.length - 1],
221
+ rest = [].slice.call(args, 1),
222
+ next = rest[0];
223
+
224
+ if (!isFunction(callback)) {
225
+ callback = null;
226
+ }
227
+
228
+ // if array, repush as args
229
+ if (isArray(args[0])) {
230
+ args[0].push(callback);
231
+ api.load.apply(null, args[0]);
232
+
233
+ return api;
234
+ }
235
+
236
+ // multiple arguments
237
+ if (!!next) {
238
+ /* Preload with text/cache hack (not good!)
239
+ * http://blog.getify.com/on-script-loaders/
240
+ * http://www.nczonline.net/blog/2010/12/21/thoughts-on-script-loaders/
241
+ * If caching is not configured correctly on the server, then items could load twice !
242
+ *************************************************************************************/
243
+ each(rest, function (item) {
244
+ // item is not a callback or empty string
245
+ if (!isFunction(item) && !!item) {
246
+ preLoad(getAsset(item));
247
+ }
248
+ });
249
+
250
+ // execute
251
+ load(getAsset(args[0]), isFunction(next) ? next : function () {
252
+ api.load.apply(null, rest);
253
+ });
254
+ }
255
+ else {
256
+ // single item
257
+ load(getAsset(args[0]));
258
+ }
259
+
260
+ return api;
261
+ }
262
+
263
+ function apiLoadAsync() {
264
+ ///<summary>
265
+ /// simply load and let browser take care of ordering
266
+ ///
267
+ /// head.load("http://domain.com/file.js","http://domain.com/file.js", callBack)
268
+ /// head.load(["http://domain.com/file.js","http://domain.com/file.js"], callBack)
269
+ /// head.load({ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }, callBack)
270
+ /// head.load([{ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }], callBack)
271
+ ///</summary>
272
+ var args = arguments,
273
+ callback = args[args.length - 1],
274
+ items = {};
275
+
276
+ if (!isFunction(callback)) {
277
+ callback = null;
278
+ }
279
+
280
+ // if array, repush as args
281
+ if (isArray(args[0])) {
282
+ args[0].push(callback);
283
+ api.load.apply(null, args[0]);
284
+
285
+ return api;
286
+ }
287
+
288
+ // JRH 262#issuecomment-26288601
289
+ // First populate the items array.
290
+ // When allLoaded is called, all items will be populated.
291
+ // Issue when lazy loaded, the callback can execute early.
292
+ each(args, function (item, i) {
293
+ if (item !== callback) {
294
+ item = getAsset(item);
295
+ items[item.name] = item;
296
+ }
297
+ });
298
+
299
+ each(args, function (item, i) {
300
+ if (item !== callback) {
301
+ item = getAsset(item);
302
+
303
+ load(item, function () {
304
+ if (allLoaded(items)) {
305
+ one(callback);
306
+ }
307
+ });
308
+ }
309
+ });
310
+
311
+ return api;
312
+ }
313
+
314
+ function load(asset, callback) {
315
+ ///<summary>Used with normal loading logic</summary>
316
+ callback = callback || noop;
317
+
318
+ if (asset.state === LOADED) {
319
+ callback();
320
+ return;
321
+ }
322
+
323
+ // INFO: why would we trigger a ready event when its not really loaded yet ?
324
+ if (asset.state === LOADING) {
325
+ api.ready(asset.name, callback);
326
+ return;
327
+ }
328
+
329
+ if (asset.state === PRELOADING) {
330
+ asset.onpreload.push(function () {
331
+ load(asset, callback);
332
+ });
333
+ return;
334
+ }
335
+
336
+ asset.state = LOADING;
337
+
338
+ loadAsset(asset, function () {
339
+ asset.state = LOADED;
340
+
341
+ callback();
342
+
343
+ // handlers for this asset
344
+ each(handlers[asset.name], function (fn) {
345
+ one(fn);
346
+ });
347
+
348
+ // dom is ready & no assets are queued for loading
349
+ // INFO: shouldn't we be doing the same test above ?
350
+ if (isDomReady && allLoaded()) {
351
+ each(handlers.ALL, function (fn) {
352
+ one(fn);
353
+ });
354
+ }
355
+ });
356
+ }
357
+
358
+ function getExtension(url) {
359
+ url = url || "";
360
+
361
+ var items = url.split("?")[0].split(".");
362
+ return items[items.length-1].toLowerCase();
363
+ }
364
+
365
+ /* Parts inspired from: https://github.com/cujojs/curl
366
+ ******************************************************/
367
+ function loadAsset(asset, callback) {
368
+ callback = callback || noop;
369
+
370
+ function error(event) {
371
+ event = event || win.event;
372
+
373
+ // release event listeners
374
+ ele.onload = ele.onreadystatechange = ele.onerror = null;
375
+
376
+ // do callback
377
+ callback();
378
+
379
+ // need some more detailed error handling here
380
+ }
381
+
382
+ function process(event) {
383
+ event = event || win.event;
384
+
385
+ // IE 7/8 (2 events on 1st load)
386
+ // 1) event.type = readystatechange, s.readyState = loading
387
+ // 2) event.type = readystatechange, s.readyState = loaded
388
+
389
+ // IE 7/8 (1 event on reload)
390
+ // 1) event.type = readystatechange, s.readyState = complete
391
+
392
+ // event.type === 'readystatechange' && /loaded|complete/.test(s.readyState)
393
+
394
+ // IE 9 (3 events on 1st load)
395
+ // 1) event.type = readystatechange, s.readyState = loading
396
+ // 2) event.type = readystatechange, s.readyState = loaded
397
+ // 3) event.type = load , s.readyState = loaded
398
+
399
+ // IE 9 (2 events on reload)
400
+ // 1) event.type = readystatechange, s.readyState = complete
401
+ // 2) event.type = load , s.readyState = complete
402
+
403
+ // event.type === 'load' && /loaded|complete/.test(s.readyState)
404
+ // event.type === 'readystatechange' && /loaded|complete/.test(s.readyState)
405
+
406
+ // IE 10 (3 events on 1st load)
407
+ // 1) event.type = readystatechange, s.readyState = loading
408
+ // 2) event.type = load , s.readyState = complete
409
+ // 3) event.type = readystatechange, s.readyState = loaded
410
+
411
+ // IE 10 (3 events on reload)
412
+ // 1) event.type = readystatechange, s.readyState = loaded
413
+ // 2) event.type = load , s.readyState = complete
414
+ // 3) event.type = readystatechange, s.readyState = complete
415
+
416
+ // event.type === 'load' && /loaded|complete/.test(s.readyState)
417
+ // event.type === 'readystatechange' && /complete/.test(s.readyState)
418
+
419
+ // Other Browsers (1 event on 1st load)
420
+ // 1) event.type = load, s.readyState = undefined
421
+
422
+ // Other Browsers (1 event on reload)
423
+ // 1) event.type = load, s.readyState = undefined
424
+
425
+ // event.type == 'load' && s.readyState = undefined
426
+
427
+ // !doc.documentMode is for IE6/7, IE8+ have documentMode
428
+ if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9))) {
429
+ // remove timeouts
430
+ win.clearTimeout(asset.errorTimeout);
431
+ win.clearTimeout(asset.cssTimeout);
432
+
433
+ // release event listeners
434
+ ele.onload = ele.onreadystatechange = ele.onerror = null;
435
+
436
+ // do callback
437
+ callback();
438
+ }
439
+ }
440
+
441
+ function isCssLoaded() {
442
+ // should we test again ? 20 retries = 5secs ..after that, the callback will be triggered by the error handler at 7secs
443
+ if (asset.state !== LOADED && asset.cssRetries <= 20) {
444
+
445
+ // loop through stylesheets
446
+ for (var i = 0, l = doc.styleSheets.length; i < l; i++) {
447
+ // do we have a match ?
448
+ // we need to tests agains ele.href and not asset.url, because a local file will be assigned the full http path on a link element
449
+ if (doc.styleSheets[i].href === ele.href) {
450
+ process({ "type": "load" });
451
+ return;
452
+ }
453
+ }
454
+
455
+ // increment & try again
456
+ asset.cssRetries++;
457
+ asset.cssTimeout = win.setTimeout(isCssLoaded, 250);
458
+ }
459
+ }
460
+
461
+ var ele;
462
+ var ext = getExtension(asset.url);
463
+
464
+ if (ext === "css") {
465
+ ele = doc.createElement("link");
466
+ ele.type = "text/" + (asset.type || "css");
467
+ ele.rel = "stylesheet";
468
+ ele.href = asset.url;
469
+
470
+ /* onload supported for CSS on unsupported browsers
471
+ * Safari windows 5.1.7, FF < 10
472
+ */
473
+
474
+ // Set counter to zero
475
+ asset.cssRetries = 0;
476
+ asset.cssTimeout = win.setTimeout(isCssLoaded, 500);
477
+ }
478
+ else {
479
+ ele = doc.createElement("script");
480
+ ele.type = "text/" + (asset.type || "javascript");
481
+ ele.src = asset.url;
482
+ }
483
+
484
+ ele.onload = ele.onreadystatechange = process;
485
+ ele.onerror = error;
486
+
487
+ /* Good read, but doesn't give much hope !
488
+ * http://blog.getify.com/on-script-loaders/
489
+ * http://www.nczonline.net/blog/2010/12/21/thoughts-on-script-loaders/
490
+ * https://hacks.mozilla.org/2009/06/defer/
491
+ */
492
+
493
+ // ASYNC: load in parallel and execute as soon as possible
494
+ ele.async = false;
495
+ // DEFER: load in parallel but maintain execution order
496
+ ele.defer = false;
497
+
498
+ // timout for asset loading
499
+ asset.errorTimeout = win.setTimeout(function () {
500
+ error({ type: "timeout" });
501
+ }, 7e3);
502
+
503
+ // use insertBefore to keep IE from throwing Operation Aborted (thx Bryan Forbes!)
504
+ var head = doc.head || doc.getElementsByTagName("head")[0];
505
+
506
+ // but insert at end of head, because otherwise if it is a stylesheet, it will not override values
507
+ head.insertBefore(ele, head.lastChild);
508
+ }
509
+
510
+ /* Parts inspired from: https://github.com/jrburke/requirejs
511
+ ************************************************************/
512
+ function init() {
513
+ var items = doc.getElementsByTagName("script");
514
+
515
+ // look for a script with a data-head-init attribute
516
+ for (var i = 0, l = items.length; i < l; i++) {
517
+ var dataMain = items[i].getAttribute("data-headjs-load");
518
+ if (!!dataMain) {
519
+ api.load(dataMain);
520
+ return;
521
+ }
522
+ }
523
+ }
524
+
525
+ function ready(key, callback) {
526
+ ///<summary>
527
+ /// INFO: use cases:
528
+ /// head.ready(callBack);
529
+ /// head.ready(document , callBack);
530
+ /// head.ready("file.js", callBack);
531
+ /// head.ready("label" , callBack);
532
+ /// head.ready(["label1", "label2"], callback);
533
+ ///</summary>
534
+
535
+ // DOM ready check: head.ready(document, function() { });
536
+ if (key === doc) {
537
+ if (isDomReady) {
538
+ one(callback);
539
+ }
540
+ else {
541
+ domWaiters.push(callback);
542
+ }
543
+
544
+ return api;
545
+ }
546
+
547
+ // shift arguments
548
+ if (isFunction(key)) {
549
+ callback = key;
550
+ key = "ALL"; // holds all callbacks that where added without labels: ready(callBack)
551
+ }
552
+
553
+ // queue all items from key and return. The callback will be executed if all items from key are already loaded.
554
+ if (isArray(key)) {
555
+ var items = {};
556
+
557
+ each(key, function (item) {
558
+ items[item] = assets[item];
559
+
560
+ api.ready(item, function() {
561
+ if (allLoaded(items)) {
562
+ one(callback);
563
+ }
564
+ });
565
+ });
566
+
567
+ return api;
568
+ }
569
+
570
+ // make sure arguments are sane
571
+ if (typeof key !== "string" || !isFunction(callback)) {
572
+ return api;
573
+ }
574
+
575
+ // this can also be called when we trigger events based on filenames & labels
576
+ var asset = assets[key];
577
+
578
+ // item already loaded --> execute and return
579
+ if (asset && asset.state === LOADED || key === "ALL" && allLoaded() && isDomReady) {
580
+ one(callback);
581
+ return api;
582
+ }
583
+
584
+ var arr = handlers[key];
585
+ if (!arr) {
586
+ arr = handlers[key] = [callback];
587
+ }
588
+ else {
589
+ arr.push(callback);
590
+ }
591
+
592
+ return api;
593
+ }
594
+
595
+ /* Mix of stuff from jQuery & IEContentLoaded
596
+ * http://dev.w3.org/html5/spec/the-end.html#the-end
597
+ ***************************************************/
598
+ function domReady() {
599
+ // Make sure body exists, at least, in case IE gets a little overzealous (jQuery ticket #5443).
600
+ if (!doc.body) {
601
+ // let's not get nasty by setting a timeout too small.. (loop mania guaranteed if assets are queued)
602
+ win.clearTimeout(api.readyTimeout);
603
+ api.readyTimeout = win.setTimeout(domReady, 50);
604
+ return;
605
+ }
606
+
607
+ if (!isDomReady) {
608
+ isDomReady = true;
609
+
610
+ init();
611
+ each(domWaiters, function (fn) {
612
+ one(fn);
613
+ });
614
+ }
615
+ }
616
+
617
+ function domContentLoaded() {
618
+ // W3C
619
+ if (doc.addEventListener) {
620
+ doc.removeEventListener("DOMContentLoaded", domContentLoaded, false);
621
+ domReady();
622
+ }
623
+
624
+ // IE
625
+ else if (doc.readyState === "complete") {
626
+ // we're here because readyState === "complete" in oldIE
627
+ // which is good enough for us to call the dom ready!
628
+ doc.detachEvent("onreadystatechange", domContentLoaded);
629
+ domReady();
630
+ }
631
+ }
632
+
633
+ // Catch cases where ready() is called after the browser event has already occurred.
634
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
635
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
636
+ if (doc.readyState === "complete") {
637
+ domReady();
638
+ }
639
+
640
+ // W3C
641
+ else if (doc.addEventListener) {
642
+ doc.addEventListener("DOMContentLoaded", domContentLoaded, false);
643
+
644
+ // A fallback to window.onload, that will always work
645
+ win.addEventListener("load", domReady, false);
646
+ }
647
+
648
+ // IE
649
+ else {
650
+ // Ensure firing before onload, maybe late but safe also for iframes
651
+ doc.attachEvent("onreadystatechange", domContentLoaded);
652
+
653
+ // A fallback to window.onload, that will always work
654
+ win.attachEvent("onload", domReady);
655
+
656
+ // If IE and not a frame
657
+ // continually check to see if the document is ready
658
+ var top = false;
659
+
660
+ try {
661
+ top = !win.frameElement && doc.documentElement;
662
+ } catch (e) { }
663
+
664
+ if (top && top.doScroll) {
665
+ (function doScrollCheck() {
666
+ if (!isDomReady) {
667
+ try {
668
+ // Use the trick by Diego Perini
669
+ // http://javascript.nwbox.com/IEContentLoaded/
670
+ top.doScroll("left");
671
+ } catch (error) {
672
+ // let's not get nasty by setting a timeout too small.. (loop mania guaranteed if assets are queued)
673
+ win.clearTimeout(api.readyTimeout);
674
+ api.readyTimeout = win.setTimeout(doScrollCheck, 50);
675
+ return;
676
+ }
677
+
678
+ // and execute any waiting functions
679
+ domReady();
680
+ }
681
+ }());
682
+ }
683
+ }
684
+ //#endregion
685
+
686
+ //#region Public Exports
687
+ // INFO: determine which method to use for loading
688
+ api.load = api.js = isAsync ? apiLoadAsync : apiLoadHack;
689
+ api.test = conditional;
690
+ api.ready = ready;
691
+ //#endregion
692
+
693
+ //#region INIT
694
+ // perform this when DOM is ready
695
+ api.ready(doc, function () {
696
+ if (allLoaded()) {
697
+ each(handlers.ALL, function (callback) {
698
+ one(callback);
699
+ });
700
+ }
701
+
702
+ if (api.feature) {
703
+ api.feature("domloaded", true);
704
+ }
705
+ });
706
+ //#endregion
707
+ }(window));