stylish 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (458) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -10
  3. data/ARCHITECTURE.md +96 -0
  4. data/Gemfile +8 -0
  5. data/README.md +25 -29
  6. data/Rakefile +24 -0
  7. data/bin/stylish +33 -0
  8. data/lib/stylish.rb +36 -1
  9. data/lib/stylish/configuration.rb +37 -0
  10. data/lib/stylish/core_ext.rb +20 -0
  11. data/lib/stylish/developer.rb +13 -0
  12. data/lib/stylish/developer/config.rb +19 -0
  13. data/lib/stylish/developer/environment.rb +75 -0
  14. data/lib/stylish/developer/listing.rb +85 -0
  15. data/lib/stylish/developer/model_delegator.rb +51 -0
  16. data/lib/stylish/developer/modification.rb +139 -0
  17. data/lib/stylish/developer/path.rb +168 -0
  18. data/lib/stylish/developer/route.rb +97 -0
  19. data/lib/stylish/developer/server.rb +40 -0
  20. data/lib/stylish/engine.rb +12 -0
  21. data/lib/stylish/fs.rb +59 -0
  22. data/lib/stylish/manifest.rb +100 -0
  23. data/lib/stylish/models.rb +119 -0
  24. data/lib/stylish/models/component.rb +19 -0
  25. data/lib/stylish/models/layout.rb +19 -0
  26. data/lib/stylish/models/library.rb +134 -0
  27. data/lib/stylish/models/package.rb +156 -0
  28. data/lib/stylish/models/script.rb +10 -0
  29. data/lib/stylish/models/stylesheet.rb +9 -0
  30. data/lib/stylish/models/template.rb +9 -0
  31. data/lib/stylish/models/theme.rb +8 -0
  32. data/lib/stylish/util.rb +20 -0
  33. data/lib/stylish/version.rb +1 -1
  34. data/library/config.json +4 -0
  35. data/library/second-theme/manifest.json +8 -0
  36. data/library/second-theme/manifest.yml +6 -0
  37. data/library/second-theme/templates/footers/footer-01.html +3 -0
  38. data/library/second-theme/templates/footers/footer-02.html +3 -0
  39. data/library/second-theme/templates/headers/header-01.html +3 -0
  40. data/library/second-theme/templates/headers/header-02.html +3 -0
  41. data/library/second-theme/templates/landing-page-blocks/landing-page-block-01.html +3 -0
  42. data/library/second-theme/templates/landing-page-blocks/landing-page-block-02.html +3 -0
  43. data/library/test-theme/components/footers/footer-01.json +5 -0
  44. data/library/test-theme/components/footers/footer-02.json +5 -0
  45. data/library/test-theme/components/headers/header-01.json +5 -0
  46. data/library/test-theme/components/headers/header-02.json +5 -0
  47. data/library/test-theme/components/landing-page-blocks/landing-page-01.json +5 -0
  48. data/library/test-theme/components/landing-page-blocks/landing-page-02.json +5 -0
  49. data/library/test-theme/manifest.json +8 -0
  50. data/library/test-theme/manifest.yml +6 -0
  51. data/library/test-theme/pages/page-01.json +11 -0
  52. data/library/test-theme/templates/footers/footer-01.html +3 -0
  53. data/library/test-theme/templates/footers/footer-02.html +3 -0
  54. data/library/test-theme/templates/headers/header-01.html +3 -0
  55. data/library/test-theme/templates/headers/header-02.html +3 -0
  56. data/library/test-theme/templates/landing-page-blocks/landing-page-block-01.html +3 -0
  57. data/library/test-theme/templates/landing-page-blocks/landing-page-block-02.html +3 -0
  58. data/library/test-theme/templates/layouts/standard-layout.html +10 -0
  59. data/spec/acceptance/listing_assets_spec.rb +20 -0
  60. data/spec/acceptance/model_browsing_spec.rb +21 -0
  61. data/spec/acceptance/model_creation_spec.rb +16 -0
  62. data/spec/acceptance/model_deleting_spec.rb +10 -0
  63. data/spec/acceptance/model_updating_spec.rb +12 -0
  64. data/spec/acceptance/modifying_assets_spec.rb +50 -0
  65. data/spec/acceptance/server_info_spec.rb +10 -0
  66. data/spec/dummy/README.rdoc +28 -0
  67. data/spec/dummy/Rakefile +6 -0
  68. data/spec/dummy/app/assets/images/.keep +0 -0
  69. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  70. data/spec/dummy/app/assets/javascripts/test.coffee +4 -0
  71. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  72. data/spec/dummy/app/assets/stylesheets/test.css.scss +6 -0
  73. data/spec/dummy/app/assets/stylesheets/writable/existing.scss.css +0 -0
  74. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  75. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  76. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  77. data/spec/dummy/app/mailers/.keep +0 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  79. data/spec/dummy/bin/bundle +3 -0
  80. data/spec/dummy/bin/rails +4 -0
  81. data/spec/dummy/bin/rake +4 -0
  82. data/spec/dummy/config.ru +4 -0
  83. data/spec/dummy/config/application.rb +30 -0
  84. data/spec/dummy/config/boot.rb +5 -0
  85. data/spec/dummy/config/database.yml +25 -0
  86. data/spec/dummy/config/environment.rb +5 -0
  87. data/spec/dummy/config/environments/development.rb +37 -0
  88. data/spec/dummy/config/environments/production.rb +82 -0
  89. data/spec/dummy/config/environments/test.rb +39 -0
  90. data/spec/dummy/config/initializers/assets.rb +8 -0
  91. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  92. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  93. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  94. data/spec/dummy/config/initializers/inflections.rb +16 -0
  95. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  96. data/spec/dummy/config/initializers/session_store.rb +3 -0
  97. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  98. data/spec/dummy/config/locales/en.yml +23 -0
  99. data/spec/dummy/config/routes.rb +3 -0
  100. data/spec/dummy/config/secrets.yml +22 -0
  101. data/spec/dummy/db/migrate/20140822065900_create_books.rb +11 -0
  102. data/spec/dummy/db/migrate/20140822065916_create_authors.rb +9 -0
  103. data/spec/dummy/db/migrate/20140824215902_create_users.rb +10 -0
  104. data/spec/dummy/db/migrate/20140826193259_create_libraries.rb +10 -0
  105. data/spec/dummy/db/schema.rb +37 -0
  106. data/spec/dummy/db/test.sqlite3 +0 -0
  107. data/spec/dummy/lib/assets/.keep +0 -0
  108. data/spec/dummy/log/.keep +0 -0
  109. data/spec/dummy/public/404.html +67 -0
  110. data/spec/dummy/public/422.html +67 -0
  111. data/spec/dummy/public/500.html +66 -0
  112. data/spec/dummy/public/favicon.ico +0 -0
  113. data/spec/fixtures/config.json +3 -0
  114. data/spec/fixtures/test-theme/components/footers/footer-01.json +5 -0
  115. data/spec/fixtures/test-theme/components/footers/footer-02.json +5 -0
  116. data/spec/fixtures/test-theme/components/headers/header-01.json +5 -0
  117. data/spec/fixtures/test-theme/components/headers/header-02.json +5 -0
  118. data/spec/fixtures/test-theme/components/landing-page-blocks/landing-page-01.json +5 -0
  119. data/spec/fixtures/test-theme/components/landing-page-blocks/landing-page-02.json +5 -0
  120. data/spec/fixtures/test-theme/manifest.json +8 -0
  121. data/spec/fixtures/test-theme/manifest.yml +6 -0
  122. data/spec/fixtures/test-theme/pages/page-01.json +11 -0
  123. data/spec/fixtures/test-theme/templates/footers/footer-01.html +3 -0
  124. data/spec/fixtures/test-theme/templates/footers/footer-02.html +3 -0
  125. data/spec/fixtures/test-theme/templates/headers/header-01.html +3 -0
  126. data/spec/fixtures/test-theme/templates/headers/header-02.html +3 -0
  127. data/spec/fixtures/test-theme/templates/landing-page-blocks/landing-page-block-01.html +3 -0
  128. data/spec/fixtures/test-theme/templates/landing-page-blocks/landing-page-block-02.html +3 -0
  129. data/spec/fixtures/test-theme/templates/layouts/standard-01.html +9 -0
  130. data/spec/lib/stylish/configuration_spec.rb +8 -0
  131. data/spec/lib/stylish/developer/path_spec.rb +36 -0
  132. data/spec/lib/stylish/developer/route_spec.rb +5 -0
  133. data/spec/lib/stylish/manifest_spec.rb +48 -0
  134. data/spec/lib/stylish/models/library_spec.rb +38 -0
  135. data/spec/lib/stylish/models/package_spec.rb +35 -0
  136. data/spec/lib/stylish/models_spec.rb +12 -0
  137. data/spec/spec_helper.rb +38 -0
  138. data/spec/support/json_helper.rb +7 -0
  139. data/spec/test.css.scss +6 -0
  140. data/stylish.gemspec +17 -2
  141. data/support/editor-app/.gitignore +2 -0
  142. data/support/editor-app/development/bower.json +9 -0
  143. data/support/editor-app/development/package.json +28 -0
  144. data/support/editor-app/development/semantic/components/accordion.css +257 -0
  145. data/support/editor-app/development/semantic/components/accordion.js +558 -0
  146. data/support/editor-app/development/semantic/components/accordion.min.css +11 -0
  147. data/support/editor-app/development/semantic/components/accordion.min.js +11 -0
  148. data/support/editor-app/development/semantic/components/ad.css +277 -0
  149. data/support/editor-app/development/semantic/components/ad.min.css +11 -0
  150. data/support/editor-app/development/semantic/components/api.js +851 -0
  151. data/support/editor-app/development/semantic/components/api.min.js +11 -0
  152. data/support/editor-app/development/semantic/components/breadcrumb.css +125 -0
  153. data/support/editor-app/development/semantic/components/breadcrumb.min.css +11 -0
  154. data/support/editor-app/development/semantic/components/button.css +2391 -0
  155. data/support/editor-app/development/semantic/components/button.min.css +11 -0
  156. data/support/editor-app/development/semantic/components/card.css +758 -0
  157. data/support/editor-app/development/semantic/components/card.min.css +11 -0
  158. data/support/editor-app/development/semantic/components/checkbox.css +514 -0
  159. data/support/editor-app/development/semantic/components/checkbox.js +507 -0
  160. data/support/editor-app/development/semantic/components/checkbox.min.css +11 -0
  161. data/support/editor-app/development/semantic/components/checkbox.min.js +11 -0
  162. data/support/editor-app/development/semantic/components/comment.css +260 -0
  163. data/support/editor-app/development/semantic/components/comment.min.css +11 -0
  164. data/support/editor-app/development/semantic/components/dimmer.css +187 -0
  165. data/support/editor-app/development/semantic/components/dimmer.js +627 -0
  166. data/support/editor-app/development/semantic/components/dimmer.min.css +11 -0
  167. data/support/editor-app/development/semantic/components/dimmer.min.js +11 -0
  168. data/support/editor-app/development/semantic/components/divider.css +244 -0
  169. data/support/editor-app/development/semantic/components/divider.min.css +11 -0
  170. data/support/editor-app/development/semantic/components/dropdown.css +1085 -0
  171. data/support/editor-app/development/semantic/components/dropdown.js +1757 -0
  172. data/support/editor-app/development/semantic/components/dropdown.min.css +11 -0
  173. data/support/editor-app/development/semantic/components/dropdown.min.js +11 -0
  174. data/support/editor-app/development/semantic/components/feed.css +277 -0
  175. data/support/editor-app/development/semantic/components/feed.min.css +11 -0
  176. data/support/editor-app/development/semantic/components/flag.css +1017 -0
  177. data/support/editor-app/development/semantic/components/flag.min.css +11 -0
  178. data/support/editor-app/development/semantic/components/form.css +875 -0
  179. data/support/editor-app/development/semantic/components/form.js +1039 -0
  180. data/support/editor-app/development/semantic/components/form.min.css +11 -0
  181. data/support/editor-app/development/semantic/components/form.min.js +11 -0
  182. data/support/editor-app/development/semantic/components/grid.css +1816 -0
  183. data/support/editor-app/development/semantic/components/grid.min.css +11 -0
  184. data/support/editor-app/development/semantic/components/header.css +572 -0
  185. data/support/editor-app/development/semantic/components/header.min.css +11 -0
  186. data/support/editor-app/development/semantic/components/icon.css +2127 -0
  187. data/support/editor-app/development/semantic/components/icon.min.css +11 -0
  188. data/support/editor-app/development/semantic/components/image.css +275 -0
  189. data/support/editor-app/development/semantic/components/image.min.css +11 -0
  190. data/support/editor-app/development/semantic/components/input.css +455 -0
  191. data/support/editor-app/development/semantic/components/input.min.css +11 -0
  192. data/support/editor-app/development/semantic/components/item.css +458 -0
  193. data/support/editor-app/development/semantic/components/item.min.css +11 -0
  194. data/support/editor-app/development/semantic/components/label.css +930 -0
  195. data/support/editor-app/development/semantic/components/label.min.css +11 -0
  196. data/support/editor-app/development/semantic/components/list.css +879 -0
  197. data/support/editor-app/development/semantic/components/list.min.css +11 -0
  198. data/support/editor-app/development/semantic/components/loader.css +279 -0
  199. data/support/editor-app/development/semantic/components/loader.min.css +11 -0
  200. data/support/editor-app/development/semantic/components/menu.css +1596 -0
  201. data/support/editor-app/development/semantic/components/menu.min.css +11 -0
  202. data/support/editor-app/development/semantic/components/message.css +422 -0
  203. data/support/editor-app/development/semantic/components/message.min.css +11 -0
  204. data/support/editor-app/development/semantic/components/modal.css +431 -0
  205. data/support/editor-app/development/semantic/components/modal.js +860 -0
  206. data/support/editor-app/development/semantic/components/modal.min.css +11 -0
  207. data/support/editor-app/development/semantic/components/modal.min.js +11 -0
  208. data/support/editor-app/development/semantic/components/nag.css +149 -0
  209. data/support/editor-app/development/semantic/components/nag.js +477 -0
  210. data/support/editor-app/development/semantic/components/nag.min.css +11 -0
  211. data/support/editor-app/development/semantic/components/nag.min.js +11 -0
  212. data/support/editor-app/development/semantic/components/popup.css +294 -0
  213. data/support/editor-app/development/semantic/components/popup.js +1187 -0
  214. data/support/editor-app/development/semantic/components/popup.min.css +11 -0
  215. data/support/editor-app/development/semantic/components/popup.min.js +11 -0
  216. data/support/editor-app/development/semantic/components/progress.css +449 -0
  217. data/support/editor-app/development/semantic/components/progress.js +785 -0
  218. data/support/editor-app/development/semantic/components/progress.min.css +11 -0
  219. data/support/editor-app/development/semantic/components/progress.min.js +11 -0
  220. data/support/editor-app/development/semantic/components/rail.css +125 -0
  221. data/support/editor-app/development/semantic/components/rail.min.css +11 -0
  222. data/support/editor-app/development/semantic/components/rating.css +262 -0
  223. data/support/editor-app/development/semantic/components/rating.js +451 -0
  224. data/support/editor-app/development/semantic/components/rating.min.css +11 -0
  225. data/support/editor-app/development/semantic/components/rating.min.js +11 -0
  226. data/support/editor-app/development/semantic/components/reset.css +430 -0
  227. data/support/editor-app/development/semantic/components/reset.min.css +11 -0
  228. data/support/editor-app/development/semantic/components/reveal.css +294 -0
  229. data/support/editor-app/development/semantic/components/reveal.min.css +11 -0
  230. data/support/editor-app/development/semantic/components/search.css +330 -0
  231. data/support/editor-app/development/semantic/components/search.js +1055 -0
  232. data/support/editor-app/development/semantic/components/search.min.css +11 -0
  233. data/support/editor-app/development/semantic/components/search.min.js +11 -0
  234. data/support/editor-app/development/semantic/components/segment.css +590 -0
  235. data/support/editor-app/development/semantic/components/segment.min.css +11 -0
  236. data/support/editor-app/development/semantic/components/shape.css +155 -0
  237. data/support/editor-app/development/semantic/components/shape.js +830 -0
  238. data/support/editor-app/development/semantic/components/shape.min.css +11 -0
  239. data/support/editor-app/development/semantic/components/shape.min.js +11 -0
  240. data/support/editor-app/development/semantic/components/sidebar.css +621 -0
  241. data/support/editor-app/development/semantic/components/sidebar.js +1084 -0
  242. data/support/editor-app/development/semantic/components/sidebar.min.css +11 -0
  243. data/support/editor-app/development/semantic/components/sidebar.min.js +11 -0
  244. data/support/editor-app/development/semantic/components/site.css +147 -0
  245. data/support/editor-app/development/semantic/components/site.js +487 -0
  246. data/support/editor-app/development/semantic/components/site.min.css +11 -0
  247. data/support/editor-app/development/semantic/components/site.min.js +11 -0
  248. data/support/editor-app/development/semantic/components/state.js +690 -0
  249. data/support/editor-app/development/semantic/components/state.min.js +11 -0
  250. data/support/editor-app/development/semantic/components/statistic.css +410 -0
  251. data/support/editor-app/development/semantic/components/statistic.min.css +11 -0
  252. data/support/editor-app/development/semantic/components/step.css +433 -0
  253. data/support/editor-app/development/semantic/components/step.min.css +11 -0
  254. data/support/editor-app/development/semantic/components/sticky.css +80 -0
  255. data/support/editor-app/development/semantic/components/sticky.js +775 -0
  256. data/support/editor-app/development/semantic/components/sticky.min.css +11 -0
  257. data/support/editor-app/development/semantic/components/sticky.min.js +11 -0
  258. data/support/editor-app/development/semantic/components/tab.css +93 -0
  259. data/support/editor-app/development/semantic/components/tab.js +787 -0
  260. data/support/editor-app/development/semantic/components/tab.min.css +11 -0
  261. data/support/editor-app/development/semantic/components/tab.min.js +11 -0
  262. data/support/editor-app/development/semantic/components/table.css +999 -0
  263. data/support/editor-app/development/semantic/components/table.min.css +11 -0
  264. data/support/editor-app/development/semantic/components/transition.css +2152 -0
  265. data/support/editor-app/development/semantic/components/transition.js +936 -0
  266. data/support/editor-app/development/semantic/components/transition.min.css +11 -0
  267. data/support/editor-app/development/semantic/components/transition.min.js +11 -0
  268. data/support/editor-app/development/semantic/components/video.css +126 -0
  269. data/support/editor-app/development/semantic/components/video.js +540 -0
  270. data/support/editor-app/development/semantic/components/video.min.css +11 -0
  271. data/support/editor-app/development/semantic/components/video.min.js +11 -0
  272. data/support/editor-app/development/semantic/components/visibility.js +970 -0
  273. data/support/editor-app/development/semantic/components/visibility.min.js +11 -0
  274. data/support/editor-app/development/semantic/semantic.css +31768 -0
  275. data/support/editor-app/development/semantic/semantic.js +18317 -0
  276. data/support/editor-app/development/semantic/semantic.min.css +11 -0
  277. data/support/editor-app/development/semantic/semantic.min.js +17 -0
  278. data/support/editor-app/development/semantic/themes/basic/assets/fonts/icons.eot +0 -0
  279. data/support/editor-app/development/semantic/themes/basic/assets/fonts/icons.svg +450 -0
  280. data/support/editor-app/development/semantic/themes/basic/assets/fonts/icons.ttf +0 -0
  281. data/support/editor-app/development/semantic/themes/basic/assets/fonts/icons.woff +0 -0
  282. data/support/editor-app/development/semantic/themes/default/assets/fonts/icons.eot +0 -0
  283. data/support/editor-app/development/semantic/themes/default/assets/fonts/icons.otf +0 -0
  284. data/support/editor-app/development/semantic/themes/default/assets/fonts/icons.svg +504 -0
  285. data/support/editor-app/development/semantic/themes/default/assets/fonts/icons.ttf +0 -0
  286. data/support/editor-app/development/semantic/themes/default/assets/fonts/icons.woff +0 -0
  287. data/support/editor-app/development/semantic/themes/default/assets/images/flags.png +0 -0
  288. data/support/editor-app/development/src/apis/index.coffee +35 -0
  289. data/support/editor-app/development/src/components/editor.cjsx +58 -0
  290. data/support/editor-app/development/src/components/editor_drawer.cjsx +7 -0
  291. data/support/editor-app/development/src/components/header.cjsx +12 -0
  292. data/support/editor-app/development/src/components/index.coffee +9 -0
  293. data/support/editor-app/development/src/components/menus/icon_grid.cjsx +0 -0
  294. data/support/editor-app/development/src/components/sidebar.cjsx +24 -0
  295. data/support/editor-app/development/src/components/tiled_grid.cjsx +35 -0
  296. data/support/editor-app/development/src/index.cjsx +82 -0
  297. data/support/editor-app/development/src/lib/util.coffee +48 -0
  298. data/support/editor-app/development/src/pages/home.cjsx +46 -0
  299. data/support/editor-app/development/src/pages/index.coffee +6 -0
  300. data/support/editor-app/development/src/pages/package_details.cjsx +55 -0
  301. data/support/editor-app/development/src/registry.coffee +35 -0
  302. data/support/editor-app/development/src/styles/components/tiled_grid.css.scss +5 -0
  303. data/support/editor-app/development/src/styles/index.css.scss +240 -0
  304. data/support/editor-app/development/src/sugar.cjsx +126 -0
  305. data/support/editor-app/development/webpack.config.js +53 -0
  306. data/support/editor-app/dist/base.css +0 -0
  307. data/support/editor-app/dist/toolit.js +62 -0
  308. data/support/editor-app/dist/toolkit.js +44573 -0
  309. data/support/editor-app/index.html +50 -0
  310. data/support/editor-app/package.json +15 -0
  311. data/support/editor-app/semantic/components/accordion.css +257 -0
  312. data/support/editor-app/semantic/components/accordion.js +558 -0
  313. data/support/editor-app/semantic/components/accordion.min.css +11 -0
  314. data/support/editor-app/semantic/components/accordion.min.js +11 -0
  315. data/support/editor-app/semantic/components/ad.css +277 -0
  316. data/support/editor-app/semantic/components/ad.min.css +11 -0
  317. data/support/editor-app/semantic/components/api.js +851 -0
  318. data/support/editor-app/semantic/components/api.min.js +11 -0
  319. data/support/editor-app/semantic/components/breadcrumb.css +125 -0
  320. data/support/editor-app/semantic/components/breadcrumb.min.css +11 -0
  321. data/support/editor-app/semantic/components/button.css +2391 -0
  322. data/support/editor-app/semantic/components/button.min.css +11 -0
  323. data/support/editor-app/semantic/components/card.css +758 -0
  324. data/support/editor-app/semantic/components/card.min.css +11 -0
  325. data/support/editor-app/semantic/components/checkbox.css +514 -0
  326. data/support/editor-app/semantic/components/checkbox.js +507 -0
  327. data/support/editor-app/semantic/components/checkbox.min.css +11 -0
  328. data/support/editor-app/semantic/components/checkbox.min.js +11 -0
  329. data/support/editor-app/semantic/components/comment.css +260 -0
  330. data/support/editor-app/semantic/components/comment.min.css +11 -0
  331. data/support/editor-app/semantic/components/dimmer.css +187 -0
  332. data/support/editor-app/semantic/components/dimmer.js +627 -0
  333. data/support/editor-app/semantic/components/dimmer.min.css +11 -0
  334. data/support/editor-app/semantic/components/dimmer.min.js +11 -0
  335. data/support/editor-app/semantic/components/divider.css +244 -0
  336. data/support/editor-app/semantic/components/divider.min.css +11 -0
  337. data/support/editor-app/semantic/components/dropdown.css +1085 -0
  338. data/support/editor-app/semantic/components/dropdown.js +1757 -0
  339. data/support/editor-app/semantic/components/dropdown.min.css +11 -0
  340. data/support/editor-app/semantic/components/dropdown.min.js +11 -0
  341. data/support/editor-app/semantic/components/feed.css +277 -0
  342. data/support/editor-app/semantic/components/feed.min.css +11 -0
  343. data/support/editor-app/semantic/components/flag.css +1017 -0
  344. data/support/editor-app/semantic/components/flag.min.css +11 -0
  345. data/support/editor-app/semantic/components/form.css +875 -0
  346. data/support/editor-app/semantic/components/form.js +1039 -0
  347. data/support/editor-app/semantic/components/form.min.css +11 -0
  348. data/support/editor-app/semantic/components/form.min.js +11 -0
  349. data/support/editor-app/semantic/components/grid.css +1816 -0
  350. data/support/editor-app/semantic/components/grid.min.css +11 -0
  351. data/support/editor-app/semantic/components/header.css +572 -0
  352. data/support/editor-app/semantic/components/header.min.css +11 -0
  353. data/support/editor-app/semantic/components/icon.css +2127 -0
  354. data/support/editor-app/semantic/components/icon.min.css +11 -0
  355. data/support/editor-app/semantic/components/image.css +275 -0
  356. data/support/editor-app/semantic/components/image.min.css +11 -0
  357. data/support/editor-app/semantic/components/input.css +455 -0
  358. data/support/editor-app/semantic/components/input.min.css +11 -0
  359. data/support/editor-app/semantic/components/item.css +458 -0
  360. data/support/editor-app/semantic/components/item.min.css +11 -0
  361. data/support/editor-app/semantic/components/label.css +930 -0
  362. data/support/editor-app/semantic/components/label.min.css +11 -0
  363. data/support/editor-app/semantic/components/list.css +879 -0
  364. data/support/editor-app/semantic/components/list.min.css +11 -0
  365. data/support/editor-app/semantic/components/loader.css +279 -0
  366. data/support/editor-app/semantic/components/loader.min.css +11 -0
  367. data/support/editor-app/semantic/components/menu.css +1596 -0
  368. data/support/editor-app/semantic/components/menu.min.css +11 -0
  369. data/support/editor-app/semantic/components/message.css +422 -0
  370. data/support/editor-app/semantic/components/message.min.css +11 -0
  371. data/support/editor-app/semantic/components/modal.css +431 -0
  372. data/support/editor-app/semantic/components/modal.js +860 -0
  373. data/support/editor-app/semantic/components/modal.min.css +11 -0
  374. data/support/editor-app/semantic/components/modal.min.js +11 -0
  375. data/support/editor-app/semantic/components/nag.css +149 -0
  376. data/support/editor-app/semantic/components/nag.js +477 -0
  377. data/support/editor-app/semantic/components/nag.min.css +11 -0
  378. data/support/editor-app/semantic/components/nag.min.js +11 -0
  379. data/support/editor-app/semantic/components/popup.css +294 -0
  380. data/support/editor-app/semantic/components/popup.js +1187 -0
  381. data/support/editor-app/semantic/components/popup.min.css +11 -0
  382. data/support/editor-app/semantic/components/popup.min.js +11 -0
  383. data/support/editor-app/semantic/components/progress.css +449 -0
  384. data/support/editor-app/semantic/components/progress.js +785 -0
  385. data/support/editor-app/semantic/components/progress.min.css +11 -0
  386. data/support/editor-app/semantic/components/progress.min.js +11 -0
  387. data/support/editor-app/semantic/components/rail.css +125 -0
  388. data/support/editor-app/semantic/components/rail.min.css +11 -0
  389. data/support/editor-app/semantic/components/rating.css +262 -0
  390. data/support/editor-app/semantic/components/rating.js +451 -0
  391. data/support/editor-app/semantic/components/rating.min.css +11 -0
  392. data/support/editor-app/semantic/components/rating.min.js +11 -0
  393. data/support/editor-app/semantic/components/reset.css +430 -0
  394. data/support/editor-app/semantic/components/reset.min.css +11 -0
  395. data/support/editor-app/semantic/components/reveal.css +294 -0
  396. data/support/editor-app/semantic/components/reveal.min.css +11 -0
  397. data/support/editor-app/semantic/components/search.css +330 -0
  398. data/support/editor-app/semantic/components/search.js +1055 -0
  399. data/support/editor-app/semantic/components/search.min.css +11 -0
  400. data/support/editor-app/semantic/components/search.min.js +11 -0
  401. data/support/editor-app/semantic/components/segment.css +590 -0
  402. data/support/editor-app/semantic/components/segment.min.css +11 -0
  403. data/support/editor-app/semantic/components/shape.css +155 -0
  404. data/support/editor-app/semantic/components/shape.js +830 -0
  405. data/support/editor-app/semantic/components/shape.min.css +11 -0
  406. data/support/editor-app/semantic/components/shape.min.js +11 -0
  407. data/support/editor-app/semantic/components/sidebar.css +621 -0
  408. data/support/editor-app/semantic/components/sidebar.js +1084 -0
  409. data/support/editor-app/semantic/components/sidebar.min.css +11 -0
  410. data/support/editor-app/semantic/components/sidebar.min.js +11 -0
  411. data/support/editor-app/semantic/components/site.css +147 -0
  412. data/support/editor-app/semantic/components/site.js +487 -0
  413. data/support/editor-app/semantic/components/site.min.css +11 -0
  414. data/support/editor-app/semantic/components/site.min.js +11 -0
  415. data/support/editor-app/semantic/components/state.js +690 -0
  416. data/support/editor-app/semantic/components/state.min.js +11 -0
  417. data/support/editor-app/semantic/components/statistic.css +410 -0
  418. data/support/editor-app/semantic/components/statistic.min.css +11 -0
  419. data/support/editor-app/semantic/components/step.css +433 -0
  420. data/support/editor-app/semantic/components/step.min.css +11 -0
  421. data/support/editor-app/semantic/components/sticky.css +80 -0
  422. data/support/editor-app/semantic/components/sticky.js +775 -0
  423. data/support/editor-app/semantic/components/sticky.min.css +11 -0
  424. data/support/editor-app/semantic/components/sticky.min.js +11 -0
  425. data/support/editor-app/semantic/components/tab.css +93 -0
  426. data/support/editor-app/semantic/components/tab.js +787 -0
  427. data/support/editor-app/semantic/components/tab.min.css +11 -0
  428. data/support/editor-app/semantic/components/tab.min.js +11 -0
  429. data/support/editor-app/semantic/components/table.css +999 -0
  430. data/support/editor-app/semantic/components/table.min.css +11 -0
  431. data/support/editor-app/semantic/components/transition.css +2152 -0
  432. data/support/editor-app/semantic/components/transition.js +936 -0
  433. data/support/editor-app/semantic/components/transition.min.css +11 -0
  434. data/support/editor-app/semantic/components/transition.min.js +11 -0
  435. data/support/editor-app/semantic/components/video.css +126 -0
  436. data/support/editor-app/semantic/components/video.js +540 -0
  437. data/support/editor-app/semantic/components/video.min.css +11 -0
  438. data/support/editor-app/semantic/components/video.min.js +11 -0
  439. data/support/editor-app/semantic/components/visibility.js +970 -0
  440. data/support/editor-app/semantic/components/visibility.min.js +11 -0
  441. data/support/editor-app/semantic/semantic.css +31768 -0
  442. data/support/editor-app/semantic/semantic.js +18317 -0
  443. data/support/editor-app/semantic/semantic.min.css +11 -0
  444. data/support/editor-app/semantic/semantic.min.js +17 -0
  445. data/support/editor-app/semantic/themes/basic/assets/fonts/icons.eot +0 -0
  446. data/support/editor-app/semantic/themes/basic/assets/fonts/icons.svg +450 -0
  447. data/support/editor-app/semantic/themes/basic/assets/fonts/icons.ttf +0 -0
  448. data/support/editor-app/semantic/themes/basic/assets/fonts/icons.woff +0 -0
  449. data/support/editor-app/semantic/themes/default/assets/fonts/icons.eot +0 -0
  450. data/support/editor-app/semantic/themes/default/assets/fonts/icons.otf +0 -0
  451. data/support/editor-app/semantic/themes/default/assets/fonts/icons.svg +504 -0
  452. data/support/editor-app/semantic/themes/default/assets/fonts/icons.ttf +0 -0
  453. data/support/editor-app/semantic/themes/default/assets/fonts/icons.woff +0 -0
  454. data/support/editor-app/semantic/themes/default/assets/images/flags.png +0 -0
  455. data/support/editor-app/vendor/jquery.js +8829 -0
  456. data/support/library-server/Gemfile +0 -0
  457. data/support/library-server/config.ru +4 -0
  458. metadata +740 -7
@@ -0,0 +1,1757 @@
1
+ /*
2
+ * # Semantic - Dropdown
3
+ * http://github.com/semantic-org/semantic-ui/
4
+ *
5
+ *
6
+ * Copyright 2014 Contributor
7
+ * Released under the MIT license
8
+ * http://opensource.org/licenses/MIT
9
+ *
10
+ */
11
+
12
+ ;(function ( $, window, document, undefined ) {
13
+
14
+ "use strict";
15
+
16
+ $.fn.dropdown = function(parameters) {
17
+ var
18
+ $allModules = $(this),
19
+ $document = $(document),
20
+
21
+ moduleSelector = $allModules.selector || '',
22
+
23
+ hasTouch = ('ontouchstart' in document.documentElement),
24
+ time = new Date().getTime(),
25
+ performance = [],
26
+
27
+ query = arguments[0],
28
+ methodInvoked = (typeof query == 'string'),
29
+ queryArguments = [].slice.call(arguments, 1),
30
+ returnedValue
31
+ ;
32
+
33
+ $allModules
34
+ .each(function() {
35
+ var
36
+ settings = ( $.isPlainObject(parameters) )
37
+ ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
38
+ : $.extend({}, $.fn.dropdown.settings),
39
+
40
+ className = settings.className,
41
+ metadata = settings.metadata,
42
+ namespace = settings.namespace,
43
+ selector = settings.selector,
44
+ error = settings.error,
45
+
46
+ eventNamespace = '.' + namespace,
47
+ moduleNamespace = 'module-' + namespace,
48
+
49
+ $module = $(this),
50
+ $text = $module.find(selector.text),
51
+ $search = $module.find(selector.search),
52
+ $input = $module.find(selector.input),
53
+
54
+ $combo = ($module.prev().find(selector.text).length > 0)
55
+ ? $module.prev().find(selector.text)
56
+ : $module.prev(),
57
+
58
+ $menu = $module.children(selector.menu),
59
+ $item = $menu.find(selector.item),
60
+
61
+ activated = false,
62
+ itemActivated = false,
63
+ element = this,
64
+ instance = $module.data(moduleNamespace),
65
+
66
+ elementNamespace,
67
+ id,
68
+ observer,
69
+ module
70
+ ;
71
+
72
+ module = {
73
+
74
+ initialize: function() {
75
+ module.debug('Initializing dropdown', settings);
76
+
77
+ if( module.is.alreadySetup() ) {
78
+ module.error(error.alreadySetup);
79
+ }
80
+ else {
81
+ module.setup.layout();
82
+ }
83
+
84
+ module.save.defaults();
85
+ module.set.selected();
86
+
87
+ module.create.id();
88
+
89
+ if(hasTouch) {
90
+ module.bind.touchEvents();
91
+ }
92
+ module.bind.mouseEvents();
93
+ module.bind.keyboardEvents();
94
+
95
+ module.observeChanges();
96
+ module.instantiate();
97
+ },
98
+
99
+ instantiate: function() {
100
+ module.verbose('Storing instance of dropdown', module);
101
+ instance = module;
102
+ $module
103
+ .data(moduleNamespace, module)
104
+ ;
105
+ },
106
+
107
+ destroy: function() {
108
+ module.verbose('Destroying previous dropdown for', $module);
109
+ module.remove.tabbable();
110
+ $module
111
+ .off(eventNamespace)
112
+ .removeData(moduleNamespace)
113
+ ;
114
+ $menu
115
+ .off(eventNamespace)
116
+ ;
117
+ $document
118
+ .off(elementNamespace)
119
+ ;
120
+ },
121
+
122
+ observeChanges: function() {
123
+ if('MutationObserver' in window) {
124
+ observer = new MutationObserver(function(mutations) {
125
+ if( module.is.selectMutation(mutations) ) {
126
+ module.debug('<select> modified, recreating menu');
127
+ module.setup.select();
128
+ }
129
+ else {
130
+ module.debug('DOM tree modified, updating selector cache');
131
+ module.refresh();
132
+ }
133
+ });
134
+ observer.observe(element, {
135
+ childList : true,
136
+ subtree : true
137
+ });
138
+ module.debug('Setting up mutation observer', observer);
139
+ }
140
+ },
141
+
142
+ create: {
143
+ id: function() {
144
+ module.verbose('Creating unique id for element');
145
+ id = module.get.uniqueID();
146
+ elementNamespace = '.' + id;
147
+ }
148
+ },
149
+
150
+ search: function() {
151
+ var
152
+ query
153
+ ;
154
+ query = $search.val();
155
+
156
+ module.verbose('Searching for query', query);
157
+ module.filter(query);
158
+ if(module.is.searchSelection() && module.can.show() ) {
159
+ module.show();
160
+ }
161
+ },
162
+
163
+ setup: {
164
+
165
+ layout: function() {
166
+ if( $module.is('select') ) {
167
+ module.setup.select();
168
+ }
169
+ if( module.is.search() && !module.is.searchable() ) {
170
+ $search = $('<input />')
171
+ .addClass(className.search)
172
+ .insertBefore($text)
173
+ ;
174
+ }
175
+ if(settings.allowTab) {
176
+ module.set.tabbable();
177
+ }
178
+ },
179
+ select: function() {
180
+ var
181
+ selectValues = module.get.selectValues()
182
+ ;
183
+ module.debug('Dropdown initialized on a select', selectValues);
184
+ if( $module.is('select') ) {
185
+ $input = $module;
186
+ }
187
+ // see if select is placed correctly already
188
+ if($input.parent(selector.dropdown).length > 0) {
189
+ module.debug('UI dropdown already exists. Creating dropdown menu only');
190
+ $module = $input.closest(selector.dropdown);
191
+ $menu = $module.children(selector.menu);
192
+ if($menu.length === 0) {
193
+ $menu = $('<div />')
194
+ .addClass(className.menu)
195
+ .appendTo($module)
196
+ ;
197
+ }
198
+ $menu.html( settings.templates.menu( selectValues ));
199
+ }
200
+ else {
201
+ module.debug('Creating entire dropdown from select');
202
+ $module = $('<div />')
203
+ .attr('class', $input.attr('class') )
204
+ .addClass(className.selection)
205
+ .addClass(className.dropdown)
206
+ .html( settings.templates.dropdown(selectValues) )
207
+ .insertBefore($input)
208
+ ;
209
+ $input
210
+ .removeAttr('class')
211
+ .prependTo($module)
212
+ ;
213
+ }
214
+ module.refresh();
215
+ }
216
+ },
217
+
218
+ refresh: function() {
219
+ module.verbose('Refreshing selector cache');
220
+ $text = $module.find(selector.text);
221
+ $search = $module.find(selector.search);
222
+ $input = $module.find(selector.input);
223
+ $combo = ($module.prev().find(selector.text).length > 0)
224
+ ? $module.prev().find(selector.text)
225
+ : $module.prev()
226
+ ;
227
+ $menu = $module.children(selector.menu);
228
+ $item = $menu.find(selector.item);
229
+ },
230
+
231
+ toggle: function() {
232
+ module.verbose('Toggling menu visibility');
233
+ if( !module.is.active() ) {
234
+ module.show();
235
+ }
236
+ else {
237
+ module.hide();
238
+ }
239
+ },
240
+
241
+ show: function(callback) {
242
+ callback = $.isFunction(callback)
243
+ ? callback
244
+ : function(){}
245
+ ;
246
+ if( module.is.searchSelection() && module.is.allFiltered() ) {
247
+ return;
248
+ }
249
+ if( module.can.show() && !module.is.active() ) {
250
+ module.debug('Showing dropdown');
251
+ module.animate.show(function() {
252
+ if( module.can.click() ) {
253
+ module.bind.intent();
254
+ }
255
+ module.set.visible();
256
+ callback.call(element);
257
+ });
258
+ settings.onShow.call(element);
259
+ }
260
+ },
261
+
262
+ hide: function(callback) {
263
+ callback = $.isFunction(callback)
264
+ ? callback
265
+ : function(){}
266
+ ;
267
+ if( module.is.active() ) {
268
+ module.debug('Hiding dropdown');
269
+ module.animate.hide(function() {
270
+ module.remove.visible();
271
+ callback.call(element);
272
+ });
273
+ settings.onHide.call(element);
274
+ }
275
+ },
276
+
277
+ hideOthers: function() {
278
+ module.verbose('Finding other dropdowns to hide');
279
+ $allModules
280
+ .not($module)
281
+ .has(selector.menu + ':visible:not(.' + className.animating + ')')
282
+ .dropdown('hide')
283
+ ;
284
+ },
285
+
286
+ hideSubMenus: function() {
287
+ var
288
+ $subMenus = $menu.find(selector.menu)
289
+ ;
290
+ $subMenus.transition('hide');
291
+ },
292
+
293
+ bind: {
294
+ keyboardEvents: function() {
295
+ module.debug('Binding keyboard events');
296
+ $module
297
+ .on('keydown' + eventNamespace, module.event.keydown)
298
+ ;
299
+ if( module.is.searchable() ) {
300
+ $module
301
+ .on(module.get.inputEvent(), selector.search, module.event.input)
302
+ ;
303
+ }
304
+ },
305
+ touchEvents: function() {
306
+ module.debug('Touch device detected binding additional touch events');
307
+ if( module.is.searchSelection() ) {
308
+ // do nothing special yet
309
+ }
310
+ else {
311
+ $module
312
+ .on('touchstart' + eventNamespace, module.event.test.toggle)
313
+ ;
314
+ }
315
+ $menu
316
+ .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
317
+ ;
318
+ },
319
+ mouseEvents: function() {
320
+ module.verbose('Mouse detected binding mouse events');
321
+ if( module.is.searchSelection() ) {
322
+ $module
323
+ .on('mousedown' + eventNamespace, selector.menu, module.event.menu.activate)
324
+ .on('mouseup' + eventNamespace, selector.menu, module.event.menu.deactivate)
325
+ .on('click' + eventNamespace, selector.search, module.show)
326
+ .on('focus' + eventNamespace, selector.search, module.event.searchFocus)
327
+ .on('blur' + eventNamespace, selector.search, module.event.searchBlur)
328
+ .on('click' + eventNamespace, selector.text, module.event.searchTextFocus)
329
+ ;
330
+ }
331
+ else {
332
+ if(settings.on == 'click') {
333
+ $module
334
+ .on('click' + eventNamespace, module.event.test.toggle)
335
+ ;
336
+ }
337
+ else if(settings.on == 'hover') {
338
+ $module
339
+ .on('mouseenter' + eventNamespace, module.delay.show)
340
+ .on('mouseleave' + eventNamespace, module.delay.hide)
341
+ ;
342
+ }
343
+ else {
344
+ $module
345
+ .on(settings.on + eventNamespace, module.toggle)
346
+ ;
347
+ }
348
+ $module
349
+ .on('mousedown' + eventNamespace, module.event.mousedown)
350
+ .on('mouseup' + eventNamespace, module.event.mouseup)
351
+ .on('focus' + eventNamespace, module.event.focus)
352
+ .on('blur' + eventNamespace, module.event.blur)
353
+ ;
354
+ }
355
+ $menu
356
+ .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
357
+ .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
358
+ .on('click' + eventNamespace, selector.item, module.event.item.click)
359
+ ;
360
+ },
361
+ intent: function() {
362
+ module.verbose('Binding hide intent event to document');
363
+ if(hasTouch) {
364
+ $document
365
+ .on('touchstart' + elementNamespace, module.event.test.touch)
366
+ .on('touchmove' + elementNamespace, module.event.test.touch)
367
+ ;
368
+ }
369
+ $document
370
+ .on('click' + elementNamespace, module.event.test.hide)
371
+ ;
372
+ }
373
+ },
374
+
375
+ unbind: {
376
+ intent: function() {
377
+ module.verbose('Removing hide intent event from document');
378
+ if(hasTouch) {
379
+ $document
380
+ .off('touchstart' + elementNamespace)
381
+ .off('touchmove' + elementNamespace)
382
+ ;
383
+ }
384
+ $document
385
+ .off('click' + elementNamespace)
386
+ ;
387
+ }
388
+ },
389
+
390
+ filter: function(searchTerm) {
391
+ var
392
+ $results = $(),
393
+ escapedTerm = module.escape.regExp(searchTerm),
394
+ exactRegExp = new RegExp('^' + escapedTerm, 'igm'),
395
+ fullTextRegExp = new RegExp(escapedTerm, 'ig'),
396
+ allItemsFiltered
397
+ ;
398
+ module.verbose('Searching for matching values');
399
+ $item
400
+ .each(function(){
401
+ var
402
+ $choice = $(this),
403
+ text = String(module.get.choiceText($choice, false)),
404
+ value = String(module.get.choiceValue($choice, text))
405
+ ;
406
+ if( text.match(exactRegExp) || value.match(exactRegExp) ) {
407
+ $results = $results.add($choice);
408
+ }
409
+ else if(settings.fullTextSearch) {
410
+ if( text.match(fullTextRegExp) || value.match(fullTextRegExp) ) {
411
+ $results = $results.add($choice);
412
+ }
413
+ }
414
+ })
415
+ ;
416
+
417
+ module.debug('Setting filter', searchTerm);
418
+ module.remove.filteredItem();
419
+ $item
420
+ .not($results)
421
+ .addClass(className.filtered)
422
+ ;
423
+
424
+ module.verbose('Selecting first non-filtered element');
425
+ module.remove.selectedItem();
426
+ $item
427
+ .not('.' + className.filtered)
428
+ .eq(0)
429
+ .addClass(className.selected)
430
+ ;
431
+ if( module.is.allFiltered() ) {
432
+ module.debug('All items filtered, hiding dropdown', searchTerm);
433
+ if(module.is.searchSelection()) {
434
+ module.hide();
435
+ }
436
+ settings.onNoResults.call(element, searchTerm);
437
+ }
438
+ },
439
+
440
+ focusSearch: function() {
441
+ if( module.is.search() ) {
442
+ $search
443
+ .focus()
444
+ ;
445
+ }
446
+ },
447
+
448
+ event: {
449
+ // prevents focus callback from occuring on mousedown
450
+ mousedown: function() {
451
+ activated = true;
452
+ },
453
+ mouseup: function() {
454
+ activated = false;
455
+ },
456
+ focus: function() {
457
+ if(!activated && module.is.hidden()) {
458
+ module.show();
459
+ }
460
+ },
461
+ blur: function(event) {
462
+ var
463
+ pageLostFocus = (document.activeElement === this)
464
+ ;
465
+ if(!activated && !pageLostFocus) {
466
+ module.hide();
467
+ }
468
+ },
469
+ searchFocus: function() {
470
+ activated = true;
471
+ module.show();
472
+ },
473
+ searchBlur: function(event) {
474
+ var
475
+ pageLostFocus = (document.activeElement === this)
476
+ ;
477
+ if(!itemActivated && !pageLostFocus) {
478
+ module.hide();
479
+ }
480
+ },
481
+ searchTextFocus: function(event) {
482
+ activated = true;
483
+ $search.focus();
484
+ },
485
+ input: function(event) {
486
+ if(module.is.searchSelection()) {
487
+ module.set.filtered();
488
+ }
489
+ clearTimeout(module.timer);
490
+ module.timer = setTimeout(module.search, settings.delay.search);
491
+ },
492
+ keydown: function(event) {
493
+ var
494
+ $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
495
+ $activeItem = $menu.children('.' + className.active).eq(0),
496
+ $selectedItem = ($currentlySelected.length > 0)
497
+ ? $currentlySelected
498
+ : $activeItem,
499
+ $visibleItems = ($selectedItem.length > 0)
500
+ ? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf()
501
+ : $menu.children(':not(.' + className.filtered +')'),
502
+ $subMenu = $selectedItem.children(selector.menu),
503
+ $parentMenu = $selectedItem.closest(selector.menu),
504
+ isSubMenuItem = $parentMenu[0] !== $menu[0],
505
+ inVisibleMenu = $parentMenu.is(':visible'),
506
+ pressedKey = event.which,
507
+ keys = {
508
+ enter : 13,
509
+ escape : 27,
510
+ leftArrow : 37,
511
+ upArrow : 38,
512
+ rightArrow : 39,
513
+ downArrow : 40
514
+ },
515
+ hasSubMenu = ($subMenu.length> 0),
516
+ hasSelectedItem = ($selectedItem.length > 0),
517
+ lastVisibleIndex = ($visibleItems.size() - 1),
518
+ $nextItem,
519
+ newIndex
520
+ ;
521
+ // visible menu keyboard shortcuts
522
+ if(module.is.visible()) {
523
+ // enter (select or sub-menu)
524
+ if(pressedKey == keys.enter && hasSelectedItem) {
525
+ if(hasSubMenu && !settings.allowCategorySelection) {
526
+ module.verbose('Pressed enter on unselectable category, opening sub menu');
527
+ pressedKey = keys.rightArrow;
528
+ }
529
+ else {
530
+ module.verbose('Enter key pressed, choosing selected item');
531
+ module.event.item.click.call($selectedItem, event);
532
+ }
533
+ }
534
+ // left arrow (hide sub-menu)
535
+ if(pressedKey == keys.leftArrow) {
536
+ if(isSubMenuItem) {
537
+ module.verbose('Left key pressed, closing sub-menu');
538
+ module.animate.hide(false, $parentMenu);
539
+ $selectedItem
540
+ .removeClass(className.selected)
541
+ ;
542
+ $parentMenu
543
+ .closest(selector.item)
544
+ .addClass(className.selected)
545
+ ;
546
+ }
547
+ event.preventDefault();
548
+ }
549
+ // right arrow (show sub-menu)
550
+ if(pressedKey == keys.rightArrow) {
551
+ if(hasSubMenu) {
552
+ module.verbose('Right key pressed, opening sub-menu');
553
+ module.animate.show(false, $subMenu);
554
+ $selectedItem
555
+ .removeClass(className.selected)
556
+ ;
557
+ $subMenu
558
+ .find(selector.item).eq(0)
559
+ .addClass(className.selected)
560
+ ;
561
+ }
562
+ event.preventDefault();
563
+ }
564
+ // up arrow (traverse menu up)
565
+ if(pressedKey == keys.upArrow) {
566
+ $nextItem = (hasSelectedItem && inVisibleMenu)
567
+ ? $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0)
568
+ : $item.eq(0)
569
+ ;
570
+ if($visibleItems.index( $nextItem ) < 0) {
571
+ module.verbose('Up key pressed but reached top of current menu');
572
+ return;
573
+ }
574
+ else {
575
+ module.verbose('Up key pressed, changing active item');
576
+ $selectedItem
577
+ .removeClass(className.selected)
578
+ ;
579
+ $nextItem
580
+ .addClass(className.selected)
581
+ ;
582
+ module.set.scrollPosition($nextItem);
583
+ }
584
+ event.preventDefault();
585
+ }
586
+ // down arrow (traverse menu down)
587
+ if(pressedKey == keys.downArrow) {
588
+ $nextItem = (hasSelectedItem && inVisibleMenu)
589
+ ? $nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0)
590
+ : $item.eq(0)
591
+ ;
592
+ if($nextItem.length === 0) {
593
+ module.verbose('Down key pressed but reached bottom of current menu');
594
+ return;
595
+ }
596
+ else {
597
+ module.verbose('Down key pressed, changing active item');
598
+ $item
599
+ .removeClass(className.selected)
600
+ ;
601
+ $nextItem
602
+ .addClass(className.selected)
603
+ ;
604
+ module.set.scrollPosition($nextItem);
605
+ }
606
+ event.preventDefault();
607
+ }
608
+ }
609
+ else {
610
+ // enter (open menu)
611
+ if(pressedKey == keys.enter) {
612
+ module.verbose('Enter key pressed, showing dropdown');
613
+ module.show();
614
+ }
615
+ // escape (close menu)
616
+ if(pressedKey == keys.escape) {
617
+ module.verbose('Escape key pressed, closing dropdown');
618
+ module.hide();
619
+ }
620
+ // down arrow (open menu)
621
+ if(pressedKey == keys.downArrow) {
622
+ module.verbose('Down key pressed, showing dropdown');
623
+ module.show();
624
+ }
625
+ }
626
+ },
627
+ test: {
628
+ toggle: function(event) {
629
+ if( module.determine.eventInMenu(event, module.toggle) ) {
630
+ event.preventDefault();
631
+ }
632
+ },
633
+ touch: function(event) {
634
+ module.determine.eventInMenu(event, function() {
635
+ if(event.type == 'touchstart') {
636
+ module.timer = setTimeout(module.hide, settings.delay.touch);
637
+ }
638
+ else if(event.type == 'touchmove') {
639
+ clearTimeout(module.timer);
640
+ }
641
+ });
642
+ event.stopPropagation();
643
+ },
644
+ hide: function(event) {
645
+ module.determine.eventInModule(event, module.hide);
646
+ }
647
+ },
648
+
649
+ menu: {
650
+ activate: function() {
651
+ itemActivated = true;
652
+ },
653
+ deactivate: function() {
654
+ itemActivated = false;
655
+ }
656
+ },
657
+ item: {
658
+ mouseenter: function(event) {
659
+ var
660
+ $subMenu = $(this).children(selector.menu),
661
+ $otherMenus = $(this).siblings(selector.item).children(selector.menu)
662
+ ;
663
+ if( $subMenu.length > 0 ) {
664
+ clearTimeout(module.itemTimer);
665
+ module.itemTimer = setTimeout(function() {
666
+ module.verbose('Showing sub-menu', $subMenu);
667
+ $.each($otherMenus, function() {
668
+ module.animate.hide(false, $(this));
669
+ });
670
+ module.animate.show(false, $subMenu);
671
+ }, settings.delay.show);
672
+ event.preventDefault();
673
+ }
674
+ },
675
+ mouseleave: function(event) {
676
+ var
677
+ $subMenu = $(this).children(selector.menu)
678
+ ;
679
+ if($subMenu.length > 0) {
680
+ clearTimeout(module.itemTimer);
681
+ module.itemTimer = setTimeout(function() {
682
+ module.verbose('Hiding sub-menu', $subMenu);
683
+ module.animate.hide(false, $subMenu);
684
+ }, settings.delay.hide);
685
+ }
686
+ },
687
+ click: function (event) {
688
+ var
689
+ $choice = $(this),
690
+ $target = $(event.target),
691
+ $subMenu = $choice.find(selector.menu),
692
+ text = module.get.choiceText($choice),
693
+ value = module.get.choiceValue($choice, text),
694
+ callback = function() {
695
+ module.remove.searchTerm();
696
+ module.determine.selectAction(text, value);
697
+ },
698
+ hasSubMenu = ($subMenu.length > 0),
699
+ isBubbledEvent = ($subMenu.find($target).length > 0)
700
+ ;
701
+ if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
702
+ callback();
703
+ }
704
+ }
705
+ },
706
+ resetStyle: function() {
707
+ $(this).removeAttr('style');
708
+ }
709
+ },
710
+
711
+ determine: {
712
+ selectAction: function(text, value) {
713
+ module.verbose('Determining action', settings.action);
714
+ if( $.isFunction( module.action[settings.action] ) ) {
715
+ module.verbose('Triggering preset action', settings.action, text, value);
716
+ module.action[ settings.action ](text, value);
717
+ }
718
+ else if( $.isFunction(settings.action) ) {
719
+ module.verbose('Triggering user action', settings.action, text, value);
720
+ settings.action(text, value);
721
+ }
722
+ else {
723
+ module.error(error.action, settings.action);
724
+ }
725
+ },
726
+ eventInModule: function(event, callback) {
727
+ callback = $.isFunction(callback)
728
+ ? callback
729
+ : function(){}
730
+ ;
731
+ if( $(event.target).closest($module).length === 0 ) {
732
+ module.verbose('Triggering event', callback);
733
+ callback();
734
+ return true;
735
+ }
736
+ else {
737
+ module.verbose('Event occurred in dropdown, canceling callback');
738
+ return false;
739
+ }
740
+ },
741
+ eventInMenu: function(event, callback) {
742
+ callback = $.isFunction(callback)
743
+ ? callback
744
+ : function(){}
745
+ ;
746
+ if( $(event.target).closest($menu).length === 0 ) {
747
+ module.verbose('Triggering event', callback);
748
+ callback();
749
+ return true;
750
+ }
751
+ else {
752
+ module.verbose('Event occurred in dropdown menu, canceling callback');
753
+ return false;
754
+ }
755
+ }
756
+ },
757
+
758
+ action: {
759
+
760
+ nothing: function() {},
761
+
762
+ activate: function(text, value) {
763
+ value = (value !== undefined)
764
+ ? value
765
+ : text
766
+ ;
767
+ module.set.selected(value);
768
+ module.hide(function() {
769
+ module.remove.filteredItem();
770
+ });
771
+ },
772
+
773
+ select: function(text, value) {
774
+ value = (value !== undefined)
775
+ ? value
776
+ : text
777
+ ;
778
+ module.set.selected(value);
779
+ module.hide(function() {
780
+ module.remove.filteredItem();
781
+ });
782
+ },
783
+
784
+ combo: function(text, value) {
785
+ value = (value !== undefined)
786
+ ? value
787
+ : text
788
+ ;
789
+ module.set.selected(value);
790
+ module.hide(function() {
791
+ module.remove.filteredItem();
792
+ });
793
+ },
794
+
795
+ hide: function() {
796
+ module.hide(function() {
797
+ module.remove.filteredItem();
798
+ });
799
+ }
800
+
801
+ },
802
+
803
+ get: {
804
+ text: function() {
805
+ return $text.text();
806
+ },
807
+ value: function() {
808
+ return ($input.length > 0)
809
+ ? $input.val()
810
+ : $module.data(metadata.value)
811
+ ;
812
+ },
813
+ choiceText: function($choice, preserveHTML) {
814
+ preserveHTML = (preserveHTML !== undefined)
815
+ ? preserveHTML
816
+ : settings.preserveHTML
817
+ ;
818
+ if($choice !== undefined) {
819
+ if($choice.find(selector.menu).length > 0) {
820
+ module.verbose('Retreiving text of element with sub-menu');
821
+ $choice = $choice.clone();
822
+ $choice.find(selector.menu).remove();
823
+ $choice.find(selector.menuIcon).remove();
824
+ }
825
+ return ($choice.data(metadata.text) !== undefined)
826
+ ? $choice.data(metadata.text)
827
+ : (preserveHTML)
828
+ ? $choice.html().trim()
829
+ : $choice.text().trim()
830
+ ;
831
+ }
832
+ },
833
+ choiceValue: function($choice, choiceText) {
834
+ choiceText = choiceText || module.get.choiceText($choice);
835
+ return ($choice.data(metadata.value) !== undefined)
836
+ ? $choice.data(metadata.value)
837
+ : (typeof choiceText === 'string')
838
+ ? choiceText.toLowerCase().trim()
839
+ : choiceText.trim()
840
+ ;
841
+ },
842
+ inputEvent: function() {
843
+ var
844
+ input = $search[0]
845
+ ;
846
+ if(input) {
847
+ return (input.oninput !== undefined)
848
+ ? 'input'
849
+ : (input.onpropertychange !== undefined)
850
+ ? 'propertychange'
851
+ : 'keyup'
852
+ ;
853
+ }
854
+ return false;
855
+ },
856
+ selectValues: function() {
857
+ var
858
+ select = {}
859
+ ;
860
+ select.values = (settings.sortSelect)
861
+ ? {} // properties will be sorted in object when re-accessed
862
+ : [] // properties will keep original order in array
863
+ ;
864
+ $module
865
+ .find('option')
866
+ .each(function() {
867
+ var
868
+ name = $(this).html(),
869
+ value = ( $(this).attr('value') !== undefined )
870
+ ? $(this).attr('value')
871
+ : name
872
+ ;
873
+ if(value === '') {
874
+ select.placeholder = name;
875
+ }
876
+ else {
877
+ if(settings.sortSelect) {
878
+ select.values[value] = {
879
+ name : name,
880
+ value : value
881
+ };
882
+ }
883
+ else {
884
+ select.values.push({
885
+ name: name,
886
+ value: value
887
+ });
888
+ }
889
+ }
890
+ })
891
+ ;
892
+ if(settings.sortSelect) {
893
+ module.debug('Retrieved and sorted values from select', select);
894
+ }
895
+ else {
896
+ module.debug('Retreived values from select', select);
897
+ }
898
+ return select;
899
+ },
900
+ activeItem: function() {
901
+ return $item.filter('.' + className.active);
902
+ },
903
+ item: function(value, strict) {
904
+ var
905
+ $selectedItem = false
906
+ ;
907
+ value = (value !== undefined)
908
+ ? value
909
+ : ( module.get.value() !== undefined)
910
+ ? module.get.value()
911
+ : module.get.text()
912
+ ;
913
+ strict = (value === '' || value === 0)
914
+ ? true
915
+ : strict || false
916
+ ;
917
+ if(value !== undefined) {
918
+ $item
919
+ .each(function() {
920
+ var
921
+ $choice = $(this),
922
+ optionText = module.get.choiceText($choice),
923
+ optionValue = module.get.choiceValue($choice, optionText)
924
+ ;
925
+ if(strict) {
926
+ module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
927
+ if( optionValue === value ) {
928
+ $selectedItem = $(this);
929
+ }
930
+ else if( !$selectedItem && optionText === value ) {
931
+ $selectedItem = $(this);
932
+ }
933
+ }
934
+ else {
935
+ if( optionValue == value ) {
936
+ module.verbose('Found select item by value', optionValue, value);
937
+ $selectedItem = $(this);
938
+ }
939
+ else if( !$selectedItem && optionText == value ) {
940
+ module.verbose('Found select item by text', optionText, value);
941
+ $selectedItem = $(this);
942
+ }
943
+ }
944
+ })
945
+ ;
946
+ }
947
+ else {
948
+ value = module.get.text();
949
+ }
950
+ return $selectedItem || false;
951
+ },
952
+ uniqueID: function() {
953
+ return (Math.random().toString(16) + '000000000').substr(2,8);
954
+ }
955
+ },
956
+
957
+ restore: {
958
+ defaults: function() {
959
+ module.restore.defaultText();
960
+ module.restore.defaultValue();
961
+ },
962
+ defaultText: function() {
963
+ var
964
+ defaultText = $module.data(metadata.defaultText)
965
+ ;
966
+ module.debug('Restoring default text', defaultText);
967
+ module.set.text(defaultText);
968
+ $text.addClass(className.placeholder);
969
+ },
970
+ defaultValue: function() {
971
+ var
972
+ defaultValue = $module.data(metadata.defaultValue)
973
+ ;
974
+ if(defaultValue !== undefined) {
975
+ module.debug('Restoring default value', defaultValue);
976
+ if(defaultValue.length) {
977
+ module.set.selected(defaultValue);
978
+ }
979
+ else {
980
+ module.remove.activeItem();
981
+ module.remove.selectedItem();
982
+ }
983
+ }
984
+ }
985
+ },
986
+
987
+ save: {
988
+ defaults: function() {
989
+ module.save.defaultText();
990
+ module.save.placeholderText();
991
+ module.save.defaultValue();
992
+ },
993
+ defaultValue: function() {
994
+ $module.data(metadata.defaultValue, module.get.value() );
995
+ },
996
+ defaultText: function() {
997
+ $module.data(metadata.defaultText, $text.text() );
998
+ },
999
+ placeholderText: function() {
1000
+ if($text.hasClass(className.placeholder)) {
1001
+ $module.data(metadata.placeholderText, $text.text());
1002
+ }
1003
+ }
1004
+ },
1005
+
1006
+ clear: function() {
1007
+ var
1008
+ placeholderText = $module.data(metadata.placeholderText)
1009
+ ;
1010
+ module.set.text(placeholderText);
1011
+ module.set.value('');
1012
+ module.remove.activeItem();
1013
+ module.remove.selectedItem();
1014
+ $text.addClass(className.placeholder);
1015
+ },
1016
+
1017
+ set: {
1018
+ filtered: function() {
1019
+ var
1020
+ searchValue = $search.val(),
1021
+ hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0)
1022
+ ;
1023
+ if(hasSearchValue) {
1024
+ $text.addClass(className.filtered);
1025
+ }
1026
+ else {
1027
+ $text.removeClass(className.filtered);
1028
+ }
1029
+ },
1030
+ tabbable: function() {
1031
+ if( module.is.searchable() ) {
1032
+ module.debug('Searchable dropdown initialized');
1033
+ $search
1034
+ .val('')
1035
+ .attr('tabindex', 0)
1036
+ ;
1037
+ $menu
1038
+ .attr('tabindex', '-1')
1039
+ ;
1040
+ }
1041
+ else {
1042
+ module.debug('Simple selection dropdown initialized');
1043
+ if(!$module.attr('tabindex') ) {
1044
+ $module
1045
+ .attr('tabindex', 0)
1046
+ ;
1047
+ $menu
1048
+ .attr('tabindex', '-1')
1049
+ ;
1050
+ }
1051
+ }
1052
+ },
1053
+ scrollPosition: function($item, forceScroll) {
1054
+ var
1055
+ edgeTolerance = 5,
1056
+ hasActive,
1057
+ offset,
1058
+ itemHeight,
1059
+ itemOffset,
1060
+ menuOffset,
1061
+ menuScroll,
1062
+ menuHeight,
1063
+ abovePage,
1064
+ belowPage
1065
+ ;
1066
+
1067
+ $item = $item || module.get.activeItem();
1068
+ hasActive = ($item && $item.length > 0);
1069
+ forceScroll = (forceScroll !== undefined)
1070
+ ? forceScroll
1071
+ : false
1072
+ ;
1073
+
1074
+ if($item && hasActive) {
1075
+
1076
+ if(!$menu.hasClass(className.visible)) {
1077
+ $menu.addClass(className.loading);
1078
+ }
1079
+
1080
+ menuHeight = $menu.height();
1081
+ itemHeight = $item.height();
1082
+ menuScroll = $menu.scrollTop();
1083
+ menuOffset = $menu.offset().top;
1084
+ itemOffset = $item.offset().top;
1085
+ offset = menuScroll - menuOffset + itemOffset;
1086
+ belowPage = menuScroll + menuHeight < (offset + edgeTolerance);
1087
+ abovePage = ((offset - edgeTolerance) < menuScroll);
1088
+ module.debug('Scrolling to active item', offset);
1089
+ if(abovePage || belowPage || forceScroll) {
1090
+ $menu
1091
+ .scrollTop(offset)
1092
+ .removeClass(className.loading)
1093
+ ;
1094
+ }
1095
+ }
1096
+ },
1097
+ text: function(text) {
1098
+ if(settings.action == 'combo') {
1099
+ module.debug('Changing combo button text', text, $combo);
1100
+ if(settings.preserveHTML) {
1101
+ $combo.html(text);
1102
+ }
1103
+ else {
1104
+ $combo.text(text);
1105
+ }
1106
+ }
1107
+ else if(settings.action !== 'select') {
1108
+ module.debug('Changing text', text, $text);
1109
+ $text
1110
+ .removeClass(className.filtered)
1111
+ .removeClass(className.placeholder)
1112
+ ;
1113
+ if(settings.preserveHTML) {
1114
+ $text.html(text);
1115
+ }
1116
+ else {
1117
+ $text.text(text);
1118
+ }
1119
+ }
1120
+ },
1121
+ value: function(value) {
1122
+ module.debug('Adding selected value to hidden input', value, $input);
1123
+ if($input.length > 0) {
1124
+ $input
1125
+ .val(value)
1126
+ .trigger('change')
1127
+ ;
1128
+ }
1129
+ else {
1130
+ $module.data(metadata.value, value);
1131
+ }
1132
+ },
1133
+ active: function() {
1134
+ $module
1135
+ .addClass(className.active)
1136
+ ;
1137
+ },
1138
+ visible: function() {
1139
+ $module.addClass(className.visible);
1140
+ },
1141
+ selected: function(value) {
1142
+ var
1143
+ $selectedItem = module.get.item(value),
1144
+ selectedText,
1145
+ selectedValue
1146
+ ;
1147
+ if($selectedItem) {
1148
+ module.debug('Setting selected menu item to', $selectedItem);
1149
+ module.remove.activeItem();
1150
+ module.remove.selectedItem();
1151
+ $selectedItem
1152
+ .addClass(className.active)
1153
+ .addClass(className.selected)
1154
+ ;
1155
+ selectedText = module.get.choiceText($selectedItem);
1156
+ selectedValue = module.get.choiceValue($selectedItem, selectedText);
1157
+ module.set.text(selectedText);
1158
+ module.set.value(selectedValue);
1159
+ settings.onChange.call(element, value, selectedText, $selectedItem);
1160
+ }
1161
+ }
1162
+ },
1163
+
1164
+ remove: {
1165
+ active: function() {
1166
+ $module.removeClass(className.active);
1167
+ },
1168
+ visible: function() {
1169
+ $module.removeClass(className.visible);
1170
+ },
1171
+ activeItem: function() {
1172
+ $item.removeClass(className.active);
1173
+ },
1174
+ filteredItem: function() {
1175
+ $item.removeClass(className.filtered);
1176
+ },
1177
+ searchTerm: function() {
1178
+ $search.val('');
1179
+ },
1180
+ selectedItem: function() {
1181
+ $item.removeClass(className.selected);
1182
+ },
1183
+ tabbable: function() {
1184
+ if( module.is.searchable() ) {
1185
+ module.debug('Searchable dropdown initialized');
1186
+ $search
1187
+ .attr('tabindex', '-1')
1188
+ ;
1189
+ $menu
1190
+ .attr('tabindex', '-1')
1191
+ ;
1192
+ }
1193
+ else {
1194
+ module.debug('Simple selection dropdown initialized');
1195
+ $module
1196
+ .attr('tabindex', '-1')
1197
+ ;
1198
+ $menu
1199
+ .attr('tabindex', '-1')
1200
+ ;
1201
+ }
1202
+ }
1203
+ },
1204
+
1205
+ is: {
1206
+ active: function() {
1207
+ return $module.hasClass(className.active);
1208
+ },
1209
+ alreadySetup: function() {
1210
+ return ($module.is('select') && $module.parent(selector.dropdown).length > 0);
1211
+ },
1212
+ animating: function($subMenu) {
1213
+ return ($subMenu)
1214
+ ? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
1215
+ : $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
1216
+ ;
1217
+ },
1218
+ allFiltered: function() {
1219
+ return ($item.filter('.' + className.filtered).length === $item.length);
1220
+ },
1221
+ hidden: function($subMenu) {
1222
+ return ($subMenu)
1223
+ ? $subMenu.is(':hidden')
1224
+ : $menu.is(':hidden')
1225
+ ;
1226
+ },
1227
+ selectMutation: function(mutations) {
1228
+ var
1229
+ selectChanged = false
1230
+ ;
1231
+ $.each(mutations, function(index, mutation) {
1232
+ if(mutation.target && $(mutation.target).is('select')) {
1233
+ selectChanged = true;
1234
+ return true;
1235
+ }
1236
+ });
1237
+ return selectChanged;
1238
+ },
1239
+ search: function() {
1240
+ return $module.hasClass(className.search);
1241
+ },
1242
+ searchable: function() {
1243
+ return ($search.length > 0);
1244
+ },
1245
+ searchSelection: function() {
1246
+ return ( module.is.searchable() && $search.parent().is($module) );
1247
+ },
1248
+ selection: function() {
1249
+ return $module.hasClass(className.selection);
1250
+ },
1251
+ upward: function() {
1252
+ return $module.hasClass(className.upward);
1253
+ },
1254
+ visible: function($subMenu) {
1255
+ return ($subMenu)
1256
+ ? $subMenu.is(':visible')
1257
+ : $menu.is(':visible')
1258
+ ;
1259
+ }
1260
+ },
1261
+
1262
+ can: {
1263
+ click: function() {
1264
+ return (hasTouch || settings.on == 'click');
1265
+ },
1266
+ show: function() {
1267
+ return !$module.hasClass(className.disabled);
1268
+ }
1269
+ },
1270
+
1271
+ animate: {
1272
+ show: function(callback, $subMenu) {
1273
+ var
1274
+ $currentMenu = $subMenu || $menu,
1275
+ start = ($subMenu)
1276
+ ? function() {}
1277
+ : function() {
1278
+ module.hideSubMenus();
1279
+ module.hideOthers();
1280
+ module.set.active();
1281
+ }
1282
+ ;
1283
+ callback = $.isFunction(callback)
1284
+ ? callback
1285
+ : function(){}
1286
+ ;
1287
+ module.set.scrollPosition(module.get.activeItem(), true);
1288
+ module.verbose('Doing menu show animation', $currentMenu);
1289
+ if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
1290
+
1291
+ if(settings.transition == 'auto') {
1292
+ settings.transition = module.is.upward()
1293
+ ? 'slide up'
1294
+ : 'slide down'
1295
+ ;
1296
+ module.verbose('Automatically determining animation based on animation direction', settings.transition);
1297
+ }
1298
+ if(settings.transition == 'none') {
1299
+ callback.call(element);
1300
+ }
1301
+ else if($.fn.transition !== undefined && $module.transition('is supported')) {
1302
+ $currentMenu
1303
+ .transition({
1304
+ animation : settings.transition + ' in',
1305
+ debug : settings.debug,
1306
+ verbose : settings.verbose,
1307
+ duration : settings.duration,
1308
+ queue : true,
1309
+ onStart : start,
1310
+ onComplete : function() {
1311
+ callback.call(element);
1312
+ }
1313
+ })
1314
+ ;
1315
+ }
1316
+ else if(settings.transition == 'slide down') {
1317
+ start();
1318
+ $currentMenu
1319
+ .hide()
1320
+ .clearQueue()
1321
+ .children()
1322
+ .clearQueue()
1323
+ .css('opacity', 0)
1324
+ .delay(50)
1325
+ .animate({
1326
+ opacity : 1
1327
+ }, settings.duration, 'easeOutQuad', module.event.resetStyle)
1328
+ .end()
1329
+ .slideDown(100, 'easeOutQuad', function() {
1330
+ module.event.resetStyle.call(this);
1331
+ callback.call(element);
1332
+ })
1333
+ ;
1334
+ }
1335
+ else if(settings.transition == 'fade') {
1336
+ start();
1337
+ $currentMenu
1338
+ .hide()
1339
+ .clearQueue()
1340
+ .fadeIn(settings.duration, function() {
1341
+ module.event.resetStyle.call(this);
1342
+ callback.call(element);
1343
+ })
1344
+ ;
1345
+ }
1346
+ else {
1347
+ module.error(error.transition, settings.transition);
1348
+ }
1349
+ }
1350
+ },
1351
+ hide: function(callback, $subMenu) {
1352
+ var
1353
+ $currentMenu = $subMenu || $menu,
1354
+ duration = ($subMenu)
1355
+ ? (settings.duration * 0.9)
1356
+ : settings.duration,
1357
+ start = ($subMenu)
1358
+ ? function() {}
1359
+ : function() {
1360
+ if( module.can.click() ) {
1361
+ module.unbind.intent();
1362
+ }
1363
+ module.focusSearch();
1364
+ module.remove.active();
1365
+ }
1366
+ ;
1367
+ callback = $.isFunction(callback)
1368
+ ? callback
1369
+ : function(){}
1370
+ ;
1371
+ if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
1372
+ module.verbose('Doing menu hide animation', $currentMenu);
1373
+
1374
+ if(settings.transition == 'auto') {
1375
+ settings.transition = module.is.upward()
1376
+ ? 'slide up'
1377
+ : 'slide down'
1378
+ ;
1379
+ }
1380
+
1381
+ if(settings.transition == 'none') {
1382
+ callback.call(element);
1383
+ }
1384
+ else if($.fn.transition !== undefined && $module.transition('is supported')) {
1385
+ $currentMenu
1386
+ .transition({
1387
+ animation : settings.transition + ' out',
1388
+ duration : settings.duration,
1389
+ debug : settings.debug,
1390
+ verbose : settings.verbose,
1391
+ queue : true,
1392
+ onStart : start,
1393
+ onComplete : function() {
1394
+ callback.call(element);
1395
+ }
1396
+ })
1397
+ ;
1398
+ }
1399
+ else if(settings.transition == 'slide down') {
1400
+ start();
1401
+ $currentMenu
1402
+ .show()
1403
+ .clearQueue()
1404
+ .children()
1405
+ .clearQueue()
1406
+ .css('opacity', 1)
1407
+ .animate({
1408
+ opacity : 0
1409
+ }, 100, 'easeOutQuad', module.event.resetStyle)
1410
+ .end()
1411
+ .delay(50)
1412
+ .slideUp(100, 'easeOutQuad', function() {
1413
+ module.event.resetStyle.call(this);
1414
+ callback.call(element);
1415
+ })
1416
+ ;
1417
+ }
1418
+ else if(settings.transition == 'fade') {
1419
+ start();
1420
+ $currentMenu
1421
+ .show()
1422
+ .clearQueue()
1423
+ .fadeOut(150, function() {
1424
+ module.event.resetStyle.call(this);
1425
+ callback.call(element);
1426
+ })
1427
+ ;
1428
+ }
1429
+ else {
1430
+ module.error(error.transition);
1431
+ }
1432
+ }
1433
+ }
1434
+ },
1435
+
1436
+ delay: {
1437
+ show: function() {
1438
+ module.verbose('Delaying show event to ensure user intent');
1439
+ clearTimeout(module.timer);
1440
+ module.timer = setTimeout(module.show, settings.delay.show);
1441
+ },
1442
+ hide: function() {
1443
+ module.verbose('Delaying hide event to ensure user intent');
1444
+ clearTimeout(module.timer);
1445
+ module.timer = setTimeout(module.hide, settings.delay.hide);
1446
+ }
1447
+ },
1448
+
1449
+ escape: {
1450
+ regExp: function(text) {
1451
+ text = String(text);
1452
+ return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
1453
+ }
1454
+ },
1455
+
1456
+ setting: function(name, value) {
1457
+ module.debug('Changing setting', name, value);
1458
+ if( $.isPlainObject(name) ) {
1459
+ $.extend(true, settings, name);
1460
+ }
1461
+ else if(value !== undefined) {
1462
+ settings[name] = value;
1463
+ }
1464
+ else {
1465
+ return settings[name];
1466
+ }
1467
+ },
1468
+ internal: function(name, value) {
1469
+ if( $.isPlainObject(name) ) {
1470
+ $.extend(true, module, name);
1471
+ }
1472
+ else if(value !== undefined) {
1473
+ module[name] = value;
1474
+ }
1475
+ else {
1476
+ return module[name];
1477
+ }
1478
+ },
1479
+ debug: function() {
1480
+ if(settings.debug) {
1481
+ if(settings.performance) {
1482
+ module.performance.log(arguments);
1483
+ }
1484
+ else {
1485
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1486
+ module.debug.apply(console, arguments);
1487
+ }
1488
+ }
1489
+ },
1490
+ verbose: function() {
1491
+ if(settings.verbose && settings.debug) {
1492
+ if(settings.performance) {
1493
+ module.performance.log(arguments);
1494
+ }
1495
+ else {
1496
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1497
+ module.verbose.apply(console, arguments);
1498
+ }
1499
+ }
1500
+ },
1501
+ error: function() {
1502
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1503
+ module.error.apply(console, arguments);
1504
+ },
1505
+ performance: {
1506
+ log: function(message) {
1507
+ var
1508
+ currentTime,
1509
+ executionTime,
1510
+ previousTime
1511
+ ;
1512
+ if(settings.performance) {
1513
+ currentTime = new Date().getTime();
1514
+ previousTime = time || currentTime;
1515
+ executionTime = currentTime - previousTime;
1516
+ time = currentTime;
1517
+ performance.push({
1518
+ 'Name' : message[0],
1519
+ 'Arguments' : [].slice.call(message, 1) || '',
1520
+ 'Element' : element,
1521
+ 'Execution Time' : executionTime
1522
+ });
1523
+ }
1524
+ clearTimeout(module.performance.timer);
1525
+ module.performance.timer = setTimeout(module.performance.display, 100);
1526
+ },
1527
+ display: function() {
1528
+ var
1529
+ title = settings.name + ':',
1530
+ totalTime = 0
1531
+ ;
1532
+ time = false;
1533
+ clearTimeout(module.performance.timer);
1534
+ $.each(performance, function(index, data) {
1535
+ totalTime += data['Execution Time'];
1536
+ });
1537
+ title += ' ' + totalTime + 'ms';
1538
+ if(moduleSelector) {
1539
+ title += ' \'' + moduleSelector + '\'';
1540
+ }
1541
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1542
+ console.groupCollapsed(title);
1543
+ if(console.table) {
1544
+ console.table(performance);
1545
+ }
1546
+ else {
1547
+ $.each(performance, function(index, data) {
1548
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
1549
+ });
1550
+ }
1551
+ console.groupEnd();
1552
+ }
1553
+ performance = [];
1554
+ }
1555
+ },
1556
+ invoke: function(query, passedArguments, context) {
1557
+ var
1558
+ object = instance,
1559
+ maxDepth,
1560
+ found,
1561
+ response
1562
+ ;
1563
+ passedArguments = passedArguments || queryArguments;
1564
+ context = element || context;
1565
+ if(typeof query == 'string' && object !== undefined) {
1566
+ query = query.split(/[\. ]/);
1567
+ maxDepth = query.length - 1;
1568
+ $.each(query, function(depth, value) {
1569
+ var camelCaseValue = (depth != maxDepth)
1570
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1571
+ : query
1572
+ ;
1573
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
1574
+ object = object[camelCaseValue];
1575
+ }
1576
+ else if( object[camelCaseValue] !== undefined ) {
1577
+ found = object[camelCaseValue];
1578
+ return false;
1579
+ }
1580
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
1581
+ object = object[value];
1582
+ }
1583
+ else if( object[value] !== undefined ) {
1584
+ found = object[value];
1585
+ return false;
1586
+ }
1587
+ else {
1588
+ module.error(error.method, query);
1589
+ return false;
1590
+ }
1591
+ });
1592
+ }
1593
+ if ( $.isFunction( found ) ) {
1594
+ response = found.apply(context, passedArguments);
1595
+ }
1596
+ else if(found !== undefined) {
1597
+ response = found;
1598
+ }
1599
+ if($.isArray(returnedValue)) {
1600
+ returnedValue.push(response);
1601
+ }
1602
+ else if(returnedValue !== undefined) {
1603
+ returnedValue = [returnedValue, response];
1604
+ }
1605
+ else if(response !== undefined) {
1606
+ returnedValue = response;
1607
+ }
1608
+ return found;
1609
+ }
1610
+ };
1611
+
1612
+ if(methodInvoked) {
1613
+ if(instance === undefined) {
1614
+ module.initialize();
1615
+ }
1616
+ module.invoke(query);
1617
+ }
1618
+ else {
1619
+ if(instance !== undefined) {
1620
+ module.destroy();
1621
+ }
1622
+ module.initialize();
1623
+ }
1624
+ })
1625
+ ;
1626
+
1627
+ return (returnedValue !== undefined)
1628
+ ? returnedValue
1629
+ : this
1630
+ ;
1631
+ };
1632
+
1633
+ $.fn.dropdown.settings = {
1634
+
1635
+ debug : false,
1636
+ verbose : true,
1637
+ performance : true,
1638
+
1639
+ on : 'click',
1640
+ action : 'activate',
1641
+
1642
+ allowTab : true,
1643
+ fullTextSearch : false,
1644
+ preserveHTML : true,
1645
+ sortSelect : false,
1646
+
1647
+ allowCategorySelection : false,
1648
+
1649
+ delay : {
1650
+ hide : 300,
1651
+ show : 200,
1652
+ search : 50,
1653
+ touch : 50
1654
+ },
1655
+
1656
+ transition : 'auto',
1657
+ duration : 250,
1658
+
1659
+ /* Callbacks */
1660
+ onNoResults : function(searchTerm){},
1661
+ onChange : function(value, text){},
1662
+ onShow : function(){},
1663
+ onHide : function(){},
1664
+
1665
+ /* Component */
1666
+
1667
+ name : 'Dropdown',
1668
+ namespace : 'dropdown',
1669
+
1670
+ error : {
1671
+ action : 'You called a dropdown action that was not defined',
1672
+ alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
1673
+ method : 'The method you called is not defined.',
1674
+ transition : 'The requested transition was not found'
1675
+ },
1676
+
1677
+ metadata: {
1678
+ defaultText : 'defaultText',
1679
+ defaultValue : 'defaultValue',
1680
+ placeholderText : 'placeholderText',
1681
+ text : 'text',
1682
+ value : 'value'
1683
+ },
1684
+
1685
+ selector : {
1686
+ dropdown : '.ui.dropdown',
1687
+ input : '> input[type="hidden"], > select',
1688
+ item : '.item',
1689
+ menu : '.menu',
1690
+ menuIcon : '.dropdown.icon',
1691
+ search : '> input.search, .menu > .search > input, .menu > input.search',
1692
+ text : '> .text:not(.icon)'
1693
+ },
1694
+
1695
+ className : {
1696
+ active : 'active',
1697
+ animating : 'animating',
1698
+ disabled : 'disabled',
1699
+ dropdown : 'ui dropdown',
1700
+ filtered : 'filtered',
1701
+ loading : 'loading',
1702
+ menu : 'menu',
1703
+ placeholder : 'default',
1704
+ search : 'search',
1705
+ selected : 'selected',
1706
+ selection : 'selection',
1707
+ upward : 'upward',
1708
+ visible : 'visible'
1709
+ }
1710
+
1711
+ };
1712
+
1713
+ /* Templates */
1714
+ $.fn.dropdown.settings.templates = {
1715
+ menu: function(select) {
1716
+ var
1717
+ placeholder = select.placeholder || false,
1718
+ values = select.values || {},
1719
+ html = ''
1720
+ ;
1721
+ $.each(select.values, function(index, option) {
1722
+ html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
1723
+ });
1724
+ return html;
1725
+ },
1726
+ dropdown: function(select) {
1727
+ var
1728
+ placeholder = select.placeholder || false,
1729
+ values = select.values || {},
1730
+ html = ''
1731
+ ;
1732
+ html += '<i class="dropdown icon"></i>';
1733
+ if(select.placeholder) {
1734
+ html += '<div class="default text">' + placeholder + '</div>';
1735
+ }
1736
+ else {
1737
+ html += '<div class="text"></div>';
1738
+ }
1739
+ html += '<div class="menu">';
1740
+ $.each(select.values, function(index, option) {
1741
+ html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
1742
+ });
1743
+ html += '</div>';
1744
+ return html;
1745
+ }
1746
+ };
1747
+
1748
+
1749
+ /* Dependencies */
1750
+ $.extend( $.easing, {
1751
+ easeOutQuad: function (x, t, b, c, d) {
1752
+ return -c *(t/=d)*(t-2) + b;
1753
+ },
1754
+ });
1755
+
1756
+
1757
+ })( jQuery, window , document );