hancock_cms 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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));