hancock_cms 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +113 -0
  9. data/Rakefile +1 -0
  10. data/app/assets/images/devices/login-bg.jpg +0 -0
  11. data/app/assets/images/rails-admin/hancock_logo.svg +5 -0
  12. data/app/assets/javascripts/hancock/app/back_to_top.coffee +24 -0
  13. data/app/assets/javascripts/hancock/cms.coffee +11 -0
  14. data/app/assets/javascripts/hancock/cms/flash.coffee +3 -0
  15. data/app/assets/javascripts/hancock/cms/init.coffee +1 -0
  16. data/app/assets/javascripts/hancock/cms/map.coffee +22 -0
  17. data/app/assets/javascripts/hancock/rails_admin/cms.ui.coffee +43 -0
  18. data/app/assets/javascripts/hancock/rails_admin/custom/ui.coffee +0 -0
  19. data/app/assets/javascripts/head.load.js +707 -0
  20. data/app/assets/javascripts/jquery.placeholder.js +157 -0
  21. data/app/assets/javascripts/rails_admin/custom/ui.coffee +2 -0
  22. data/app/assets/stylesheets/hancock/cms.sass +9 -0
  23. data/app/assets/stylesheets/hancock/cms/devise.sass +157 -0
  24. data/app/assets/stylesheets/hancock/cms/flash.sass +69 -0
  25. data/app/assets/stylesheets/hancock/cms/mixins.sass +98 -0
  26. data/app/assets/stylesheets/hancock/cms/normalize.scss +407 -0
  27. data/app/assets/stylesheets/hancock/cms/powered.sass +18 -0
  28. data/app/assets/stylesheets/hancock/rails_admin/cms.theming.sass +703 -0
  29. data/app/assets/stylesheets/hancock/rails_admin/custom/theming.sass +1 -0
  30. data/app/assets/stylesheets/hancock/toplink/toplink.sass +24 -0
  31. data/app/assets/stylesheets/rails_admin/custom/theming.sass +4 -0
  32. data/app/controllers/concerns/hancock/current_user.rb +12 -0
  33. data/app/controllers/concerns/hancock/decorators/home.rb +12 -0
  34. data/app/controllers/concerns/hancock/decorators/registrations.rb +5 -0
  35. data/app/controllers/concerns/hancock/decorators/sessions.rb +5 -0
  36. data/app/controllers/concerns/hancock/errors.rb +94 -0
  37. data/app/controllers/concerns/hancock/fancybox.rb +14 -0
  38. data/app/controllers/concerns/hancock/no_cache.rb +12 -0
  39. data/app/controllers/hancock/home_controller.rb +10 -0
  40. data/app/controllers/hancock/registrations_controller.rb +23 -0
  41. data/app/controllers/hancock/sessions_controller.rb +24 -0
  42. data/app/helpers/hancock/gzip_helper.rb +27 -0
  43. data/app/helpers/hancock/home_helper.rb +2 -0
  44. data/app/helpers/hancock/powered_helper.rb +42 -0
  45. data/app/models/concerns/hancock/boolean_field.rb +21 -0
  46. data/app/models/concerns/hancock/cacheable.rb +33 -0
  47. data/app/models/concerns/hancock/decorators/embedded_element.rb +28 -0
  48. data/app/models/concerns/hancock/enableable.rb +8 -0
  49. data/app/models/concerns/hancock/geocodeable.rb +4 -0
  50. data/app/models/concerns/hancock/hash_field.rb +113 -0
  51. data/app/models/concerns/hancock/html_field.rb +33 -0
  52. data/app/models/concerns/hancock/mappable.rb +91 -0
  53. data/app/models/concerns/hancock/model_localizeable.rb +33 -0
  54. data/app/models/concerns/hancock/rails_admin_patch.rb +86 -0
  55. data/app/models/concerns/hancock/sort_field.rb +20 -0
  56. data/app/models/concerns/hancock/sortable.rb +8 -0
  57. data/app/models/hancock/embedded_element.rb +17 -0
  58. data/app/views/blocks/_favicon.html.slim +60 -0
  59. data/app/views/blocks/_footer.html.slim +1 -0
  60. data/app/views/blocks/_header.html.slim +3 -0
  61. data/app/views/devise/passwords/edit.html.slim +29 -0
  62. data/app/views/devise/passwords/new.html.slim +19 -0
  63. data/app/views/devise/registrations/edit.html.slim +31 -0
  64. data/app/views/devise/registrations/new.html.slim +39 -0
  65. data/app/views/devise/sessions/new.html.slim +39 -0
  66. data/app/views/devise/shared/_links.html.slim +11 -0
  67. data/app/views/hancock/errors/_base.html.slim +3 -0
  68. data/app/views/hancock/errors/error_403.html.slim +1 -0
  69. data/app/views/hancock/errors/error_404.html.slim +1 -0
  70. data/app/views/hancock/errors/error_500.html.slim +1 -0
  71. data/app/views/hancock/home/index.html.slim +1 -0
  72. data/app/views/hancock/simple_captcha/_simple_captcha.html.slim +13 -0
  73. data/app/views/hancock/toplink/_toplink.html.slim +2 -0
  74. data/app/views/layouts/application.html.slim +35 -0
  75. data/app/views/layouts/hancock/devise/confirmations.html.slim +22 -0
  76. data/app/views/layouts/hancock/devise/passwords.html.slim +22 -0
  77. data/app/views/layouts/hancock/devise/registrations.html.slim +22 -0
  78. data/app/views/layouts/hancock/devise/sessions.html.slim +22 -0
  79. data/app/views/layouts/hancock/devise/unlocks.html.slim +22 -0
  80. data/app/views/layouts/rails_admin/_footer.html.slim +2 -0
  81. data/app/views/layouts/rails_admin/_footer_navigation.html.slim +20 -0
  82. data/app/views/layouts/rails_admin/_navigation.html.slim +73 -0
  83. data/app/views/layouts/rails_admin/_secondary_navigation.html.slim +32 -0
  84. data/app/views/layouts/rails_admin/application.html.haml +68 -0
  85. data/app/views/layouts/rails_admin/pjax.html.haml +17 -0
  86. data/app/views/rails_admin/main/_check_boxes.html.slim +27 -0
  87. data/app/views/rails_admin/main/_enum_check_boxes.html.slim +5 -0
  88. data/app/views/rails_admin/main/_enum_radio_buttons.html.slim +5 -0
  89. data/app/views/rails_admin/main/_form_hancock_multiselect.html.slim +48 -0
  90. data/app/views/rails_admin/main/_form_raw.html.slim +1 -0
  91. data/app/views/rails_admin/main/_hancock_hash.html.slim +9 -0
  92. data/app/views/rails_admin/main/_hancock_hash_ml.html.slim +10 -0
  93. data/app/views/rails_admin/main/_hancock_html.html.slim +16 -0
  94. data/app/views/rails_admin/main/_hancock_html_ml.html.slim +53 -0
  95. data/app/views/shared/_admin_link.html.slim +3 -0
  96. data/app/views/shared/_messages.html.slim +7 -0
  97. data/config/initializers/embedded_findable.rb +57 -0
  98. data/config/initializers/hancock_cms.rb +11 -0
  99. data/config/initializers/simple_captcha.rb +70 -0
  100. data/config/locales/en.hancock.yml +29 -0
  101. data/config/locales/en.hancock_admin.yml +6 -0
  102. data/config/locales/ru.cancan.yml +4 -0
  103. data/config/locales/ru.devise.yml +65 -0
  104. data/config/locales/ru.hancock.yml +36 -0
  105. data/config/locales/ru.hancock_admin.yml +6 -0
  106. data/config/locales/ru.models.yml +82 -0
  107. data/config/locales/ru.mongoid.yml +450 -0
  108. data/config/locales/ru.rails_admin.yml +168 -0
  109. data/hancock_cms.gemspec +46 -0
  110. data/lib/filename_to_slug.rb +32 -0
  111. data/lib/generators/hancock/cms/ability_generator.rb +14 -0
  112. data/lib/generators/hancock/cms/admin_generator.rb +21 -0
  113. data/lib/generators/hancock/cms/application_generator.rb +14 -0
  114. data/lib/generators/hancock/cms/assets_generator.rb +35 -0
  115. data/lib/generators/hancock/cms/config_generator.rb +13 -0
  116. data/lib/generators/hancock/cms/controllers/decorators_generator.rb +27 -0
  117. data/lib/generators/hancock/cms/gemfile_generator.rb +13 -0
  118. data/lib/generators/hancock/cms/layout_generator.rb +14 -0
  119. data/lib/generators/hancock/cms/model_generator.rb +39 -0
  120. data/lib/generators/hancock/cms/models/embedded_element_generator.rb +56 -0
  121. data/lib/generators/hancock/cms/models/templates/embedded_element.erb +47 -0
  122. data/lib/generators/hancock/cms/paperclip_optimizer_generator.rb +13 -0
  123. data/lib/generators/hancock/cms/rack_generator.rb +12 -0
  124. data/lib/generators/hancock/cms/robots_generator.rb +14 -0
  125. data/lib/generators/hancock/cms/scripts_generator.rb +31 -0
  126. data/lib/generators/hancock/cms/templates/Gemfile.erb +69 -0
  127. data/lib/generators/hancock/cms/templates/ability.erb +49 -0
  128. data/lib/generators/hancock/cms/templates/admin.erb +74 -0
  129. data/lib/generators/hancock/cms/templates/application.erb +42 -0
  130. data/lib/generators/hancock/cms/templates/assets/javascripts/application.coffee.erb +5 -0
  131. data/lib/generators/hancock/cms/templates/assets/stylesheets/application.sass.erb +88 -0
  132. data/lib/generators/hancock/cms/templates/hancock_cms.erb +30 -0
  133. data/lib/generators/hancock/cms/templates/model.erb +42 -0
  134. data/lib/generators/hancock/cms/templates/paperclip_optimizer.erb +80 -0
  135. data/lib/generators/hancock/cms/templates/rack.erb +15 -0
  136. data/lib/generators/hancock/cms/templates/robots.txt.erb +5 -0
  137. data/lib/generators/hancock/cms/templates/scripts/assets_precompile.sh +3 -0
  138. data/lib/generators/hancock/cms/templates/scripts/bundle_production.sh +4 -0
  139. data/lib/generators/hancock/cms/templates/scripts/db_dump.sh.erb +3 -0
  140. data/lib/generators/hancock/cms/templates/scripts/db_restore.sh +3 -0
  141. data/lib/generators/hancock/cms/templates/scripts/full_assets_precompile.sh +4 -0
  142. data/lib/generators/hancock/cms/templates/scripts/restart_thru_kill.sh +3 -0
  143. data/lib/generators/hancock/cms/templates/scripts/send_hup.sh +3 -0
  144. data/lib/generators/hancock/cms/templates/scripts/send_usr2.sh +3 -0
  145. data/lib/generators/hancock/cms/templates/scripts/server.sh +5 -0
  146. data/lib/generators/hancock/cms/templates/scripts/server_alt.sh +5 -0
  147. data/lib/generators/hancock/cms/templates/unicorn.erb +57 -0
  148. data/lib/generators/hancock/cms/templates/unicorn.god.erb +59 -0
  149. data/lib/generators/hancock/cms/unicorn_god_generator.rb +15 -0
  150. data/lib/generators/hancock/cms/utils.rb +21 -0
  151. data/lib/hancock/admin.rb +60 -0
  152. data/lib/hancock/admin/embedded_element.rb +26 -0
  153. data/lib/hancock/configuration.rb +48 -0
  154. data/lib/hancock/controller.rb +30 -0
  155. data/lib/hancock/engine.rb +48 -0
  156. data/lib/hancock/migration.rb +15 -0
  157. data/lib/hancock/model.rb +53 -0
  158. data/lib/hancock/models/embedded_element.rb +12 -0
  159. data/lib/hancock/models/mongoid/embedded_element.rb +14 -0
  160. data/lib/hancock/plugin.rb +25 -0
  161. data/lib/hancock/plugin_configuration.rb +30 -0
  162. data/lib/hancock/rails_admin_ext/config.rb +129 -0
  163. data/lib/hancock/rails_admin_ext/hancock_hash.rb +84 -0
  164. data/lib/hancock/rails_admin_ext/hancock_html.rb +79 -0
  165. data/lib/hancock/rails_admin_ext/hancock_multiselect.rb +44 -0
  166. data/lib/hancock/rails_admin_ext/hancock_slugs.rb +35 -0
  167. data/lib/hancock/rails_admin_ext/patches/field_patch.rb +14 -0
  168. data/lib/hancock/rails_admin_ext/patches/group_patch.rb +41 -0
  169. data/lib/hancock/rails_admin_ext/patches/hancock_cms_group.rb +61 -0
  170. data/lib/hancock/rails_admin_ext/patches/new_controller_patch.rb +54 -0
  171. data/lib/hancock/routes.rb +20 -0
  172. data/lib/hancock/simple_form_patch.rb +12 -0
  173. data/lib/hancock/tasks.rb +13 -0
  174. data/lib/hancock/version.rb +3 -0
  175. data/lib/hancock_cms.rb +130 -0
  176. data/lib/manual_slug.rb +10 -0
  177. data/lib/manual_slug/active_record.rb +32 -0
  178. data/lib/manual_slug/mongoid.rb +40 -0
  179. data/lib/rails_admin/custom_show_in_app.rb +43 -0
  180. data/release.sh +12 -0
  181. data/template.rb +564 -0
  182. metadata +455 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2bb11bbd769e8fe10d0b729feec21bab3dbc0d6f
4
+ data.tar.gz: 9c1e705aadab3d37bacde39c8db2f987ce0800c5
5
+ SHA512:
6
+ metadata.gz: 041b271b62472f1e9a23a554be65e845a47b59115144b2dca7b2485d20b6d598f380dd0b879ec66556ae75d2e1ea3eb690689287ef9ab2b1dd7b87e8c7168f1d
7
+ data.tar.gz: e6877df62eb2d1275f466d8bf53d4b0936a272ca86238424b9ffc67cd26c8105bbbaf18cc0890f6469d5ac531e8188a38571ad541c2ee017c5a98ddfe911f3a8
data/.gitignore ADDED
@@ -0,0 +1,23 @@
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
+
21
+ mongoid/Gemfile.lock
22
+ activerecord/Gemfile.lock
23
+ /Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ hancock_cms_rails4
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hancock_cms.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Alexander Kiseliev
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.
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # HancockCMS
2
+
3
+ #### Inspired by [RocketCMS](https://github.com/rs-pro/rocket_cms)
4
+ ### Remaded from [EnjoyCMS](https://github.com/enjoycreative/enjoy_cms)
5
+
6
+ # DEVELOPMENT VERSION
7
+
8
+ Rails + RailsAdmin + Mongoid/PostgreSQL CMS
9
+
10
+ Very opinionated and tuned for my needs.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'hancock_cms_mongoid', '~> 1.0'
17
+
18
+ or:
19
+
20
+ gem 'hancock_cms_activerecord', '~> 1.0'
21
+
22
+ *Only PostgreSQL is tested or supported for AR(from root repo). 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 hancock_cms -v 1.0
31
+
32
+ For activerecord, generate migrations and run them
33
+
34
+ rails g rails_admin_settings:migration
35
+ rails g hancock_cms:migration
36
+ rake db:migrate
37
+
38
+ ## Usage
39
+
40
+ ### Using app generator
41
+
42
+ Make sure you have rails 4.2 installed
43
+
44
+ rails -v
45
+
46
+ If not, uninstall rails and install again
47
+
48
+ gem uninstall rails
49
+ gem install rails -v 4.2
50
+
51
+ Then, for mongoid:
52
+
53
+ rails new my_app -T -O -m https://raw.githubusercontent.com/red-rocks/hancock_cms/rails4/template.rb
54
+
55
+ for ActiveRecord:
56
+
57
+ rails new my_app -T --database=postgresql -m https://raw.githubusercontent.com/red-rocks/hancock_cms/rails4/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
+ ### Localization
62
+
63
+ All models included in the gem support localization via either [hstore_translate](https://github.com/Leadformance/hstore_translate) or built-in Mongoid localize: true option.
64
+
65
+ You can get a nice admin UI for editing locales by adding [rails_admin_hstore_translate](https://github.com/glebtv/rails_admin_hstore_translate) or [rails_admin_mongoid_localize_field](https://github.com/sudosu/rails_admin_mongoid_localize_field)
66
+
67
+ <!-- Wrap your routes with locale scope:
68
+ ```ruby
69
+ scope "(:locale)", locale: /en|ru/ do
70
+ hancock_cms_routes
71
+ end
72
+ ``` -->
73
+
74
+ Enable localization in HancockCMS:
75
+
76
+ ```ruby
77
+ Hancock.configure do |hancock|
78
+ hancock.localize = true
79
+ ...
80
+ end
81
+ ```
82
+
83
+ Add ```rails_admin_hstore_translate``` or ```hstore_translate``` gem if using PostgreSQL:
84
+
85
+ ```ruby
86
+ gem 'rails_admin_hstore_translate'
87
+ ```
88
+
89
+ or
90
+
91
+ ```ruby
92
+ gem 'hstore_translate'
93
+ ```
94
+
95
+ Add ```rails_admin_mongoid_localize_field``` gem if using MongoDB:
96
+
97
+ ```ruby
98
+ gem 'rails_admin_mongoid_localize_field'
99
+ ```
100
+
101
+ ### Documentation
102
+
103
+ It's basically Mongoid + Rails Admin + some of my common models and controllers, etc.
104
+
105
+ See their documentation for more info
106
+
107
+ ## Contributing
108
+
109
+ 1. Fork it
110
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
111
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
112
+ 4. Push to the branch (`git push origin my-new-feature`)
113
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="hancock_logo" width="2925" height="512" viewBox="0 0 2925 512">
4
+ <path fill="#fff" d="M272.303 133.032l67.375 59.112 11.639-6.226 34.906-133.816 3.2-11.226-201.31-38.169 73.832 121.192 10.36 9.135zM618.658 125.816h55.506v97.921h122.706v-97.921h55.506v260.424h-55.506v-107.695h-122.648v107.695h-55.506v-260.424zM2527.032 218.095l26.881 2.734c-2.232 15.304-9.528 28.6-20.088 38.424-9.416 7.832-21.576 12.561-34.848 12.561-0.441 0-0.889-0.009-1.334-0.016-0.696 0.040-1.592 0.065-2.49 0.065-16.936 0-31.96-8.184-41.329-20.81-9.769-13.622-15.56-30.448-15.56-48.632 0-0.935 0.015-1.863 0.043-2.784-0.040-0.776-0.063-1.839-0.063-2.91 0-18.44 6.36-35.385 17-48.782 10.113-12.36 25.56-20.296 42.857-20.296 0.68 0 1.353 0.009 2.030 0.040q45.168-0.006 53.782 47.704l-26.881 3.666q-3.494-25.72-25.368-25.774c-0.414-0.024-0.903-0.040-1.385-0.040-9.633 0-17.945 5.64-21.823 13.8-4.632 9.352-7.305 20.192-7.305 31.656 0 0.744 0.008 1.487 0.034 2.226-0.056 0.832-0.088 1.928-0.088 3.034 0 10.632 2.84 20.601 7.8 29.192 4.018 6.729 11.559 11.359 20.175 11.359 0.177 0 0.354-0.002 0.53-0.008 13.646 0 22.778-8.785 27.258-26.414v0zM2784.258 268.946h-32.76v-86.168q0-26.881-23.854-26.824c-0.296-0.008-0.647-0.018-0.992-0.018-8.52 0-16.12 3.937-21.079 10.088-5.288 7.53-8.426 16.824-8.426 26.856 0 1.215 0.046 2.423 0.136 3.608l-0.008 72.456h-33.16v-86.168c0-18.152-7.448-27.288-22.344-27.288-0.056-0-0.127-0-0.199-0-9.129 0-17.266 4.28-22.504 10.936-5.864 7.537-9.368 17.058-9.368 27.4 0 0.887 0.024 1.761 0.073 2.632l-0.008 72.488h-32.232v-138.36h30.312v29.44q14.776-32.346 46.135-32.346t39.736 32.346q16.696-32.346 46.135-32.346c0.664-0.040 1.448-0.056 2.232-0.056 23.296 0 42.184 18.888 42.184 42.184 0 0.472-0.008 0.936-0.024 1.407l0.002 97.736zM2805.202 237.12l29.095-5.816q6.746 16.815 29.615 16.815 29.095 0 29.095-17.106c0.001-0.038 0.001-0.073 0.001-0.12 0-3.647-1.775-6.879-4.505-8.879-3-2.367-6.599-4.057-10.52-4.824l-25.352-4.793q-41.946-8.088-41.946-40.728c-0.006-0.192-0.008-0.423-0.008-0.648 0-12.040 5.096-22.891 13.247-30.52 8.923-8.52 22.072-12.824 39.646-12.824q43.814 0 53.586 32.232l-27.814 5.816c-2.968-10.415-11.226-15.592-24.904-15.592q-24.96 0-24.96 15.592c0 7.214 6.746 12.216 20.135 14.894l29.672 5.704q34.906 7.16 34.906 39.736c0.039 0.616 0.056 1.336 0.056 2.063 0 13.482-7.066 25.32-17.704 31.999-11.662 7.192-25.608 11.4-40.536 11.4-0.678 0-1.351-0.009-2.019-0.024-0.298 0.009-0.776 0.010-1.242 0.010-13.198 0-25.655-3.19-36.632-8.832-9.944-4.967-17.691-14.152-20.833-25.274l-0.072-0.287zM1051.243 168.584l72.026 217.656h-58.824l-65.224-201.776c-0.75-2.712-2.12-5.048-3.96-6.927-1.606-1.375-3.704-2.216-6.008-2.216-0.12 0-0.232 0.002-0.35 0.008-0.056-0.006-0.149-0.007-0.232-0.007-2.15 0-4.104 0.822-5.576 2.162-1.784 1.84-3.091 4.168-3.698 6.76l-65.303 201.992h-59.112l71.624-217.656c4.21-14.686 12.337-27.128 23.176-36.52 10.158-7.398 22.76-11.784 36.393-11.784 1.006 0 2.008 0.024 3 0.072 0.689-0.041 1.663-0.070 2.64-0.070 13.934 0 26.809 4.52 37.25 12.168 10.728 9 18.664 21.336 22.184 35.425l0.101 0.466zM1264.833 180.506l39.272 138.008c1.192 5.551 3.464 10.44 6.584 14.648 2.191 2.106 5.288 3.471 8.705 3.471 0.266 0 0.536-0.009 0.802-0.024 0.217 0.023 0.52 0.031 0.824 0.031 3.765 0 7.144-1.624 9.487-4.207 2.256-3.057 3.608-6.888 3.608-11.031 0-0.464-0.017-0.92-0.050-1.378l0.006-194.209h55.506v200.615q0 30.546-17.92 47.825t-50.040 17.454q-29.094 0-45.321-13.56c-10.761-9.016-19.32-24.495-25.544-46.546l-39.215-138.296c-1.144-5.496-3.353-10.344-6.416-14.536-2.186-2.104-5.288-3.464-8.703-3.464-0.266 0-0.536 0.008-0.802 0.024-0.264-0.024-0.608-0.040-0.958-0.040-3.704 0-7.048 1.558-9.416 4.047-2.216 2.984-3.545 6.737-3.545 10.798 0 0.482 0.022 0.958 0.056 1.432l-0.007 194.673h-55.561v-201.192q0-30.374 17.976-47.48t50.040-16.986q29.094 0 45.321 13.559c10.761 9.016 19.32 24.494 25.544 46.546v0zM1503.781 125.64h114.909v54.401h-109.615c-0.712-0.056-1.535-0.088-2.37-0.088-8.048 0-15.384 3.034-20.935 8.024-4.904 5.608-7.912 13.032-7.912 21.16 0 0.839 0.032 1.665 0.094 2.488l-0.008 88.68c-0.152 1.081-0.233 2.337-0.233 3.608 0 15.327 12.425 27.752 27.752 27.752 1.272 0 2.526-0.088 3.752-0.248l109.416 0.016v54.808h-114.854q-38.107 0-59.752-21.704t-21.64-60.041v-97.336q0-38.281 21.64-59.866t59.752-21.528v0zM1732.436 175.16c-0.681-0.056-1.48-0.086-2.288-0.086-8.072 0-15.434 3.032-21.016 8.024-4.903 5.512-7.912 12.856-7.912 20.898 0 0.824 0.032 1.643 0.094 2.456l-0.008 98.802c-0.152 1.081-0.233 2.337-0.233 3.608 0 15.327 12.425 27.752 27.752 27.752 1.272 0 2.526-0.088 3.752-0.248l73.752 0.016c1.081 0.152 2.337 0.233 3.608 0.233 15.328 0 27.752-12.425 27.752-27.752 0-1.272-0.088-2.526-0.248-3.752l0.016-98.767c0.056-0.703 0.088-1.522 0.088-2.345 0-8.042-3.015-15.384-7.97-20.953-5.52-4.934-12.888-7.961-20.954-7.961-0.808 0-1.607 0.030-2.392 0.088l-73.784-0.008zM1727.145 120.345h84.361q38.344 0 59.928 21.641t21.64 59.752v107.87q0 38.281-21.64 60.041t-59.928 21.816h-84.424q-38.107 0-59.695-21.816t-21.64-60.041v-107.695q0-38.168 21.64-59.752t59.695-21.641v0zM2006.012 125.585h114.91v54.401h-109.615c-0.712-0.056-1.535-0.088-2.37-0.088-8.048 0-15.384 3.034-20.935 8.024-4.904 5.608-7.912 13.032-7.912 21.16 0 0.839 0.032 1.665 0.094 2.488l-0.008 88.735c-0.152 1.081-0.233 2.337-0.233 3.608 0 15.327 12.425 27.752 27.752 27.752 1.272 0 2.526-0.088 3.752-0.248l109.416 0.016v54.808h-114.909q-38.107 0-59.752-21.704t-21.64-60.041v-97.336q0-38.281 21.64-59.866t59.752-21.528v0zM2149.49 125.585h55.506v98.152h38.632q31.535 0 44.334-6.456c8.705-4.392 15.104-12.28 17.408-21.768l19.656-69.695h58.184l-24.728 83.201c-3.096 11.512-9.361 21.281-17.793 28.625-8.744 7.095-19.545 11.831-31.383 13.178 12.887 0.962 24.84 5.442 34.842 12.504 7.521 6.199 14.27 19.112 20.146 38.839l25.425 84.072h-59.345l-19.72-72.376q-5.816-20.826-18.039-28.104t-46.080-7.272h-41.425v107.752h-55.506v-260.424zM25.259 375.768l-7.561 8.841 164.888 121.72-13.96-141.269-5.352-12.68-35.374-83.546-12.104 0.346-90.648 106.648zM10.658 158.344l140.455 5.816 8.84 10.535-50.792 92.392-100.306 97.575-7.736-206.721 9.544 0.408zM0.821 149.559v4.774l0.408-4.186v-1.161l-0.408 0.584zM173.569 16.144l83.256 110.952-2.504 13.095-100.306 17.864-140.8-19.144 153.426-132.015 6.921 9.254zM174.435 0.144v0zM399.546 42.733v0zM491.24 240.84l-126.664 56.026-12.216-5.352 4.361-89.601 0.64-13.734 48.696-133.176 95.707 181.176-10.534 4.655zM408.851 440.469l10.24 5.352 82.094-187.87-134.695 45.094-84.015 60.454 3.432 12.974 122.936 64zM401.584 458.792l-197.935 53.352-2.214-11.639-26.586-135.975 7.912-10.76 99.666 27.928 119.16 77.147zM235.008 265.688v0l-56.84 76.975-10.648-3.080-29.559-71.041 97.048-2.854zM246.178 267.784l-57.425 77.906 73.135 21 9.079-6.456-24.786-92.454zM254.849 260.334v0l87.68 38.226-0.584 11.055-61.848 44.28-25.016-93.44zM254.436 248.696l84.536-44.68 8.32 7.386-4.186 76.28-88.666-38.695zM261.713 154.792l1.28-6.865 10.936-1.864 56.841 50.616-85.586 45.56 16.466-87.272zM234.193 245.146v0l-62.081-72.146 5.816-10.12 74.472-12.744-18.214 95.014zM245.249 242.184v0 0zM229.65 255.624l-95.592 3.546-4.248-10.184 36.946-66.441z"></path>
5
+ </svg>
@@ -0,0 +1,24 @@
1
+ slide_to_top = () ->
2
+
3
+ pos = $(window).scrollTop()
4
+
5
+ if pos > 100
6
+ $('.toplink').addClass('active')
7
+
8
+ $(window).scroll ->
9
+ if $(this).scrollTop() > 100
10
+ $('.toplink').addClass('active')
11
+ else
12
+ $('.toplink').removeClass('active')
13
+
14
+ $('.toplink').click ->
15
+ $('html, body').stop().animate { scrollTop: 0 }, 500,'swing', ->
16
+ $('.toplink').removeClass('active')
17
+ return false
18
+ return false
19
+
20
+ $(window).on 'load', ->
21
+ slide_to_top()
22
+
23
+ $(document).bind "page:load", ->
24
+ slide_to_top()
@@ -0,0 +1,11 @@
1
+ #= require jquery
2
+ #= require jquery_ujs
3
+
4
+ # require turbolinks
5
+
6
+ #= require ../head.load.js
7
+ #= require ../jquery.placeholder.js
8
+
9
+ #= require ./cms/init
10
+ #= require ./cms/map
11
+ #= require ./cms/flash
@@ -0,0 +1,3 @@
1
+ $(document).on('click.close_flash', 'a.close_flash', ->
2
+ $(this).parents('.message').fadeOut()
3
+ )
@@ -0,0 +1 @@
1
+ window.hancock_cms ||= {}
@@ -0,0 +1,22 @@
1
+ window.ya_init = ->
2
+ $('.ymap').not('.done').addClass('done').each ->
3
+ $m = $(this)
4
+ coord = [$m.data('lat'), $m.data('lon')]
5
+ map = new ymaps.Map($m[0],
6
+ center: coord
7
+ zoom: 14,
8
+ behaviors: ['default'] #, 'scrollZoom']
9
+ )
10
+ map.controls.add('zoomControl', { left: 5, top: 5 })
11
+ obj = new ymaps.Placemark(coord,
12
+ hintContent: $m.data('hint')
13
+ balloonContent: $m.data('hint') + ' ' + $m.data('addr')
14
+ )
15
+ map.geoObjects.add obj
16
+
17
+ $(document).on 'page:change', ->
18
+ return if $('.ymap').not('.done').length == 0
19
+ if window.ymaps
20
+ ya_init()
21
+ else
22
+ head.load "//api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU&onload=ya_init"
@@ -0,0 +1,43 @@
1
+ #= require jquery.mCustomScrollbar.concat.min
2
+
3
+ window.hancock_cms ||= {}
4
+ window.hancock_cms.multiselect_dblclick = (selector)->
5
+ $(document).delegate selector + ' .ra-multiselect-left select option', 'dblclick', (e)->
6
+ $(e.currentTarget).closest('.ra-multiselect').find('.ra-multiselect-center .ra-multiselect-item-add').click()
7
+
8
+ $(document).delegate selector + ' .ra-multiselect-right select option', 'dblclick', (e)->
9
+ $(e.currentTarget).closest('.ra-multiselect').find('.ra-multiselect-center .ra-multiselect-item-remove').click()
10
+
11
+ window.hancock_cms.multiselect_dblclick("select.hancock_multiselect + .ra-multiselect")
12
+
13
+
14
+ $(document).delegate '.toolbar .nav .dropdown-header', 'click', (e)->
15
+ e.preventDefault()
16
+ _target = $(e.currentTarget).toggleClass('opened')
17
+ li = _target.next()
18
+ loop
19
+ li.toggleClass('visible')
20
+ li = li.next()
21
+ break if li.length == 0 or li.hasClass('dropdown-header')
22
+
23
+ $(document).on 'pjax:complete ready', ()->
24
+ active_nav_element = $(".toolbar .nav .active")
25
+ if active_nav_element.length > 0
26
+ _parent = active_nav_element.prevAll(".dropdown-header:first")
27
+ if _parent.length > 0 and !_parent.hasClass('opened')
28
+ _parent.click()
29
+
30
+ mscroll = () ->
31
+ $('.toolbar').mCustomScrollbar(
32
+ scrollInertia: 60
33
+ mouseWheelPixels: 60
34
+ theme: 'minimal'
35
+ mouseWheel:
36
+ scrollAmount: 0
37
+ )
38
+
39
+ $(window).on 'load', ->
40
+ mscroll()
41
+
42
+ $(document).bind "page:load", ->
43
+ mscroll()
@@ -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));