vapid 0.1.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 (433) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +6 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +133 -0
  6. data/.travis.yml +5 -0
  7. data/Gemfile +10 -0
  8. data/README.md +37 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/exe/vapid +7 -0
  13. data/lib/vapid.rb +24 -0
  14. data/lib/vapid/assets/javascripts/vapid/admin.coffee +2 -0
  15. data/lib/vapid/assets/stylesheets/vapid/admin.scss +72 -0
  16. data/lib/vapid/builder.rb +70 -0
  17. data/lib/vapid/cli.rb +96 -0
  18. data/lib/vapid/controllers/admin_controller.rb +282 -0
  19. data/lib/vapid/controllers/project_controller.rb +41 -0
  20. data/lib/vapid/db/migrate/20170202182310_create_groups.rb +12 -0
  21. data/lib/vapid/db/migrate/20170202183017_create_records.rb +11 -0
  22. data/lib/vapid/db/migrate/20170202185150_create_users.rb +11 -0
  23. data/lib/vapid/directive.rb +168 -0
  24. data/lib/vapid/directives.rb +30 -0
  25. data/lib/vapid/directives/audio.rb +27 -0
  26. data/lib/vapid/directives/group.rb +71 -0
  27. data/lib/vapid/directives/hide.rb +11 -0
  28. data/lib/vapid/directives/href.rb +11 -0
  29. data/lib/vapid/directives/image.rb +14 -0
  30. data/lib/vapid/directives/richtext.rb +15 -0
  31. data/lib/vapid/directives/show.rb +11 -0
  32. data/lib/vapid/directives/text.rb +24 -0
  33. data/lib/vapid/directives/video.rb +28 -0
  34. data/lib/vapid/generator_template/.gitignore +21 -0
  35. data/lib/vapid/generator_template/Gemfile.tt +13 -0
  36. data/lib/vapid/generator_template/README.md +0 -0
  37. data/lib/vapid/generator_template/assets/favicon.ico +0 -0
  38. data/lib/vapid/generator_template/assets/images/.keep +0 -0
  39. data/lib/vapid/generator_template/assets/javascripts/.keep +0 -0
  40. data/lib/vapid/generator_template/assets/stylesheets/.keep +0 -0
  41. data/lib/vapid/generator_template/assets/stylesheets/application.css +120 -0
  42. data/lib/vapid/generator_template/config.ru +3 -0
  43. data/lib/vapid/generator_template/config/database.yml +12 -0
  44. data/lib/vapid/generator_template/config/settings.yml.tt +11 -0
  45. data/lib/vapid/generator_template/templates/index.html.erb +25 -0
  46. data/lib/vapid/generator_template/templates/layouts/default.html.erb +22 -0
  47. data/lib/vapid/models.rb +18 -0
  48. data/lib/vapid/models/group.rb +36 -0
  49. data/lib/vapid/models/record.rb +30 -0
  50. data/lib/vapid/models/user.rb +16 -0
  51. data/lib/vapid/server.rb +93 -0
  52. data/lib/vapid/settings.rb +13 -0
  53. data/lib/vapid/template.rb +79 -0
  54. data/lib/vapid/template/node.rb +91 -0
  55. data/lib/vapid/template/parser.rb +50 -0
  56. data/lib/vapid/vendor/semantic-ui/.versions +4 -0
  57. data/lib/vapid/vendor/semantic-ui/LICENSE +22 -0
  58. data/lib/vapid/vendor/semantic-ui/README.md +7 -0
  59. data/lib/vapid/vendor/semantic-ui/components/accordion.css +252 -0
  60. data/lib/vapid/vendor/semantic-ui/components/accordion.js +610 -0
  61. data/lib/vapid/vendor/semantic-ui/components/accordion.min.css +9 -0
  62. data/lib/vapid/vendor/semantic-ui/components/accordion.min.js +10 -0
  63. data/lib/vapid/vendor/semantic-ui/components/ad.css +275 -0
  64. data/lib/vapid/vendor/semantic-ui/components/ad.min.css +10 -0
  65. data/lib/vapid/vendor/semantic-ui/components/api.js +1167 -0
  66. data/lib/vapid/vendor/semantic-ui/components/api.min.js +10 -0
  67. data/lib/vapid/vendor/semantic-ui/components/breadcrumb.css +124 -0
  68. data/lib/vapid/vendor/semantic-ui/components/breadcrumb.min.css +9 -0
  69. data/lib/vapid/vendor/semantic-ui/components/button.css +3450 -0
  70. data/lib/vapid/vendor/semantic-ui/components/button.min.css +9 -0
  71. data/lib/vapid/vendor/semantic-ui/components/card.css +964 -0
  72. data/lib/vapid/vendor/semantic-ui/components/card.min.css +9 -0
  73. data/lib/vapid/vendor/semantic-ui/components/checkbox.css +625 -0
  74. data/lib/vapid/vendor/semantic-ui/components/checkbox.js +831 -0
  75. data/lib/vapid/vendor/semantic-ui/components/checkbox.min.css +9 -0
  76. data/lib/vapid/vendor/semantic-ui/components/checkbox.min.js +10 -0
  77. data/lib/vapid/vendor/semantic-ui/components/colorize.js +274 -0
  78. data/lib/vapid/vendor/semantic-ui/components/colorize.min.js +11 -0
  79. data/lib/vapid/vendor/semantic-ui/components/comment.css +270 -0
  80. data/lib/vapid/vendor/semantic-ui/components/comment.min.css +9 -0
  81. data/lib/vapid/vendor/semantic-ui/components/container.css +147 -0
  82. data/lib/vapid/vendor/semantic-ui/components/container.min.css +9 -0
  83. data/lib/vapid/vendor/semantic-ui/components/dimmer.css +200 -0
  84. data/lib/vapid/vendor/semantic-ui/components/dimmer.js +708 -0
  85. data/lib/vapid/vendor/semantic-ui/components/dimmer.min.css +9 -0
  86. data/lib/vapid/vendor/semantic-ui/components/dimmer.min.js +10 -0
  87. data/lib/vapid/vendor/semantic-ui/components/divider.css +260 -0
  88. data/lib/vapid/vendor/semantic-ui/components/divider.min.css +9 -0
  89. data/lib/vapid/vendor/semantic-ui/components/dropdown.css +1442 -0
  90. data/lib/vapid/vendor/semantic-ui/components/dropdown.js +3767 -0
  91. data/lib/vapid/vendor/semantic-ui/components/dropdown.min.css +9 -0
  92. data/lib/vapid/vendor/semantic-ui/components/dropdown.min.js +11 -0
  93. data/lib/vapid/vendor/semantic-ui/components/embed.css +166 -0
  94. data/lib/vapid/vendor/semantic-ui/components/embed.js +696 -0
  95. data/lib/vapid/vendor/semantic-ui/components/embed.min.css +9 -0
  96. data/lib/vapid/vendor/semantic-ui/components/embed.min.js +10 -0
  97. data/lib/vapid/vendor/semantic-ui/components/feed.css +296 -0
  98. data/lib/vapid/vendor/semantic-ui/components/feed.min.css +9 -0
  99. data/lib/vapid/vendor/semantic-ui/components/flag.css +1031 -0
  100. data/lib/vapid/vendor/semantic-ui/components/flag.min.css +9 -0
  101. data/lib/vapid/vendor/semantic-ui/components/form.css +1067 -0
  102. data/lib/vapid/vendor/semantic-ui/components/form.js +1603 -0
  103. data/lib/vapid/vendor/semantic-ui/components/form.min.css +9 -0
  104. data/lib/vapid/vendor/semantic-ui/components/form.min.js +10 -0
  105. data/lib/vapid/vendor/semantic-ui/components/grid.css +2002 -0
  106. data/lib/vapid/vendor/semantic-ui/components/grid.min.css +9 -0
  107. data/lib/vapid/vendor/semantic-ui/components/header.css +721 -0
  108. data/lib/vapid/vendor/semantic-ui/components/header.min.css +9 -0
  109. data/lib/vapid/vendor/semantic-ui/components/icon.css +3292 -0
  110. data/lib/vapid/vendor/semantic-ui/components/icon.min.css +9 -0
  111. data/lib/vapid/vendor/semantic-ui/components/image.css +306 -0
  112. data/lib/vapid/vendor/semantic-ui/components/image.min.css +9 -0
  113. data/lib/vapid/vendor/semantic-ui/components/input.css +510 -0
  114. data/lib/vapid/vendor/semantic-ui/components/input.min.css +9 -0
  115. data/lib/vapid/vendor/semantic-ui/components/item.css +486 -0
  116. data/lib/vapid/vendor/semantic-ui/components/item.min.css +9 -0
  117. data/lib/vapid/vendor/semantic-ui/components/label.css +1307 -0
  118. data/lib/vapid/vendor/semantic-ui/components/label.min.css +9 -0
  119. data/lib/vapid/vendor/semantic-ui/components/list.css +951 -0
  120. data/lib/vapid/vendor/semantic-ui/components/list.min.css +9 -0
  121. data/lib/vapid/vendor/semantic-ui/components/loader.css +347 -0
  122. data/lib/vapid/vendor/semantic-ui/components/loader.min.css +9 -0
  123. data/lib/vapid/vendor/semantic-ui/components/menu.css +2002 -0
  124. data/lib/vapid/vendor/semantic-ui/components/menu.min.css +1 -0
  125. data/lib/vapid/vendor/semantic-ui/components/message.css +477 -0
  126. data/lib/vapid/vendor/semantic-ui/components/message.min.css +9 -0
  127. data/lib/vapid/vendor/semantic-ui/components/modal.css +502 -0
  128. data/lib/vapid/vendor/semantic-ui/components/modal.js +913 -0
  129. data/lib/vapid/vendor/semantic-ui/components/modal.min.css +9 -0
  130. data/lib/vapid/vendor/semantic-ui/components/modal.min.js +10 -0
  131. data/lib/vapid/vendor/semantic-ui/components/nag.css +147 -0
  132. data/lib/vapid/vendor/semantic-ui/components/nag.js +507 -0
  133. data/lib/vapid/vendor/semantic-ui/components/nag.min.css +9 -0
  134. data/lib/vapid/vendor/semantic-ui/components/nag.min.js +10 -0
  135. data/lib/vapid/vendor/semantic-ui/components/popup.css +733 -0
  136. data/lib/vapid/vendor/semantic-ui/components/popup.js +1475 -0
  137. data/lib/vapid/vendor/semantic-ui/components/popup.min.css +9 -0
  138. data/lib/vapid/vendor/semantic-ui/components/popup.min.js +10 -0
  139. data/lib/vapid/vendor/semantic-ui/components/progress.css +516 -0
  140. data/lib/vapid/vendor/semantic-ui/components/progress.js +931 -0
  141. data/lib/vapid/vendor/semantic-ui/components/progress.min.css +9 -0
  142. data/lib/vapid/vendor/semantic-ui/components/progress.min.js +10 -0
  143. data/lib/vapid/vendor/semantic-ui/components/rail.css +152 -0
  144. data/lib/vapid/vendor/semantic-ui/components/rail.min.css +9 -0
  145. data/lib/vapid/vendor/semantic-ui/components/rating.css +263 -0
  146. data/lib/vapid/vendor/semantic-ui/components/rating.js +508 -0
  147. data/lib/vapid/vendor/semantic-ui/components/rating.min.css +9 -0
  148. data/lib/vapid/vendor/semantic-ui/components/rating.min.js +10 -0
  149. data/lib/vapid/vendor/semantic-ui/components/reset.css +424 -0
  150. data/lib/vapid/vendor/semantic-ui/components/reset.min.css +9 -0
  151. data/lib/vapid/vendor/semantic-ui/components/reveal.css +284 -0
  152. data/lib/vapid/vendor/semantic-ui/components/reveal.min.css +9 -0
  153. data/lib/vapid/vendor/semantic-ui/components/search.css +408 -0
  154. data/lib/vapid/vendor/semantic-ui/components/search.js +1442 -0
  155. data/lib/vapid/vendor/semantic-ui/components/search.min.css +9 -0
  156. data/lib/vapid/vendor/semantic-ui/components/search.min.js +10 -0
  157. data/lib/vapid/vendor/semantic-ui/components/segment.css +798 -0
  158. data/lib/vapid/vendor/semantic-ui/components/segment.min.css +9 -0
  159. data/lib/vapid/vendor/semantic-ui/components/shape.css +157 -0
  160. data/lib/vapid/vendor/semantic-ui/components/shape.js +921 -0
  161. data/lib/vapid/vendor/semantic-ui/components/shape.min.css +9 -0
  162. data/lib/vapid/vendor/semantic-ui/components/shape.min.js +10 -0
  163. data/lib/vapid/vendor/semantic-ui/components/sidebar.css +634 -0
  164. data/lib/vapid/vendor/semantic-ui/components/sidebar.js +1036 -0
  165. data/lib/vapid/vendor/semantic-ui/components/sidebar.min.css +9 -0
  166. data/lib/vapid/vendor/semantic-ui/components/sidebar.min.js +10 -0
  167. data/lib/vapid/vendor/semantic-ui/components/site.css +160 -0
  168. data/lib/vapid/vendor/semantic-ui/components/site.js +487 -0
  169. data/lib/vapid/vendor/semantic-ui/components/site.min.css +9 -0
  170. data/lib/vapid/vendor/semantic-ui/components/site.min.js +10 -0
  171. data/lib/vapid/vendor/semantic-ui/components/state.js +708 -0
  172. data/lib/vapid/vendor/semantic-ui/components/state.min.js +10 -0
  173. data/lib/vapid/vendor/semantic-ui/components/statistic.css +569 -0
  174. data/lib/vapid/vendor/semantic-ui/components/statistic.min.css +9 -0
  175. data/lib/vapid/vendor/semantic-ui/components/step.css +623 -0
  176. data/lib/vapid/vendor/semantic-ui/components/step.min.css +9 -0
  177. data/lib/vapid/vendor/semantic-ui/components/sticky.css +78 -0
  178. data/lib/vapid/vendor/semantic-ui/components/sticky.js +942 -0
  179. data/lib/vapid/vendor/semantic-ui/components/sticky.min.css +9 -0
  180. data/lib/vapid/vendor/semantic-ui/components/sticky.min.js +10 -0
  181. data/lib/vapid/vendor/semantic-ui/components/tab.css +91 -0
  182. data/lib/vapid/vendor/semantic-ui/components/tab.js +952 -0
  183. data/lib/vapid/vendor/semantic-ui/components/tab.min.css +9 -0
  184. data/lib/vapid/vendor/semantic-ui/components/tab.min.js +10 -0
  185. data/lib/vapid/vendor/semantic-ui/components/table.css +1108 -0
  186. data/lib/vapid/vendor/semantic-ui/components/table.min.css +9 -0
  187. data/lib/vapid/vendor/semantic-ui/components/transition.css +1964 -0
  188. data/lib/vapid/vendor/semantic-ui/components/transition.js +1095 -0
  189. data/lib/vapid/vendor/semantic-ui/components/transition.min.css +9 -0
  190. data/lib/vapid/vendor/semantic-ui/components/transition.min.js +10 -0
  191. data/lib/vapid/vendor/semantic-ui/components/video.css +125 -0
  192. data/lib/vapid/vendor/semantic-ui/components/video.js +532 -0
  193. data/lib/vapid/vendor/semantic-ui/components/video.min.css +10 -0
  194. data/lib/vapid/vendor/semantic-ui/components/video.min.js +11 -0
  195. data/lib/vapid/vendor/semantic-ui/components/visibility.js +1288 -0
  196. data/lib/vapid/vendor/semantic-ui/components/visibility.min.js +10 -0
  197. data/lib/vapid/vendor/semantic-ui/components/visit.js +517 -0
  198. data/lib/vapid/vendor/semantic-ui/components/visit.min.js +11 -0
  199. data/lib/vapid/vendor/semantic-ui/package.js +34 -0
  200. data/lib/vapid/vendor/semantic-ui/package.json +20 -0
  201. data/lib/vapid/vendor/semantic-ui/semantic.css +36844 -0
  202. data/lib/vapid/vendor/semantic-ui/semantic.js +22617 -0
  203. data/lib/vapid/vendor/semantic-ui/semantic.min.css +364 -0
  204. data/lib/vapid/vendor/semantic-ui/semantic.min.js +19 -0
  205. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.eot +0 -0
  206. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.otf +0 -0
  207. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.svg +2671 -0
  208. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.ttf +0 -0
  209. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.woff +0 -0
  210. data/lib/vapid/vendor/semantic-ui/themes/default/assets/fonts/icons.woff2 +0 -0
  211. data/lib/vapid/vendor/semantic-ui/themes/default/assets/images/flags.png +0 -0
  212. data/lib/vapid/vendor/trix/.blade.yml +45 -0
  213. data/lib/vapid/vendor/trix/.github/ISSUE_TEMPLATE.md +13 -0
  214. data/lib/vapid/vendor/trix/.gitignore +3 -0
  215. data/lib/vapid/vendor/trix/.ruby-version +1 -0
  216. data/lib/vapid/vendor/trix/.travis.yml +6 -0
  217. data/lib/vapid/vendor/trix/CONDUCT.md +79 -0
  218. data/lib/vapid/vendor/trix/Gemfile +17 -0
  219. data/lib/vapid/vendor/trix/Gemfile.lock +152 -0
  220. data/lib/vapid/vendor/trix/LICENSE +20 -0
  221. data/lib/vapid/vendor/trix/README.md +382 -0
  222. data/lib/vapid/vendor/trix/assets/index.html +55 -0
  223. data/lib/vapid/vendor/trix/assets/trix-core.coffee +2 -0
  224. data/lib/vapid/vendor/trix/assets/trix.coffee +3 -0
  225. data/lib/vapid/vendor/trix/assets/trix.scss +5 -0
  226. data/lib/vapid/vendor/trix/assets/trix/banner/index.coffee.erb +3 -0
  227. data/lib/vapid/vendor/trix/assets/trix/banner/index.scss.erb +3 -0
  228. data/lib/vapid/vendor/trix/assets/trix/banner/index.txt.erb +3 -0
  229. data/lib/vapid/vendor/trix/assets/trix/images/README.md +6 -0
  230. data/lib/vapid/vendor/trix/assets/trix/images/attach.svg +5 -0
  231. data/lib/vapid/vendor/trix/assets/trix/images/bold.svg +5 -0
  232. data/lib/vapid/vendor/trix/assets/trix/images/bullets.svg +5 -0
  233. data/lib/vapid/vendor/trix/assets/trix/images/code.svg +5 -0
  234. data/lib/vapid/vendor/trix/assets/trix/images/heading_1.svg +5 -0
  235. data/lib/vapid/vendor/trix/assets/trix/images/italic.svg +5 -0
  236. data/lib/vapid/vendor/trix/assets/trix/images/link.svg +6 -0
  237. data/lib/vapid/vendor/trix/assets/trix/images/nesting_level_decrease.svg +5 -0
  238. data/lib/vapid/vendor/trix/assets/trix/images/nesting_level_increase.svg +5 -0
  239. data/lib/vapid/vendor/trix/assets/trix/images/numbers.svg +5 -0
  240. data/lib/vapid/vendor/trix/assets/trix/images/quote.svg +5 -0
  241. data/lib/vapid/vendor/trix/assets/trix/images/redo.svg +5 -0
  242. data/lib/vapid/vendor/trix/assets/trix/images/remove.svg +4 -0
  243. data/lib/vapid/vendor/trix/assets/trix/images/strike.svg +6 -0
  244. data/lib/vapid/vendor/trix/assets/trix/images/trash.svg +5 -0
  245. data/lib/vapid/vendor/trix/assets/trix/images/undo.svg +5 -0
  246. data/lib/vapid/vendor/trix/assets/trix/stylesheets/attachments.scss +112 -0
  247. data/lib/vapid/vendor/trix/assets/trix/stylesheets/content.scss +88 -0
  248. data/lib/vapid/vendor/trix/assets/trix/stylesheets/editor.scss +8 -0
  249. data/lib/vapid/vendor/trix/assets/trix/stylesheets/icons.scss +14 -0
  250. data/lib/vapid/vendor/trix/assets/trix/stylesheets/media-queries.scss +7 -0
  251. data/lib/vapid/vendor/trix/assets/trix/stylesheets/toolbar.scss +194 -0
  252. data/lib/vapid/vendor/trix/bin/blade +16 -0
  253. data/lib/vapid/vendor/trix/bin/ci +21 -0
  254. data/lib/vapid/vendor/trix/bin/rackup +16 -0
  255. data/lib/vapid/vendor/trix/bin/rake +16 -0
  256. data/lib/vapid/vendor/trix/bin/release +139 -0
  257. data/lib/vapid/vendor/trix/bin/setup +69 -0
  258. data/lib/vapid/vendor/trix/bin/update-status-image +100 -0
  259. data/lib/vapid/vendor/trix/bower.json +34 -0
  260. data/lib/vapid/vendor/trix/config.ru +32 -0
  261. data/lib/vapid/vendor/trix/dist/trix-core.js +11 -0
  262. data/lib/vapid/vendor/trix/dist/trix.css +286 -0
  263. data/lib/vapid/vendor/trix/dist/trix.js +20 -0
  264. data/lib/vapid/vendor/trix/package.json +29 -0
  265. data/lib/vapid/vendor/trix/polyfills/polyfills.coffee +3 -0
  266. data/lib/vapid/vendor/trix/polyfills/set.coffee +24 -0
  267. data/lib/vapid/vendor/trix/polyfills/vendor/CustomElements.js +1029 -0
  268. data/lib/vapid/vendor/trix/polyfills/vendor/README.md +2 -0
  269. data/lib/vapid/vendor/trix/polyfills/vendor/promise.js +228 -0
  270. data/lib/vapid/vendor/trix/src/trix/VERSION +1 -0
  271. data/lib/vapid/vendor/trix/src/trix/config/block_attributes.coffee +37 -0
  272. data/lib/vapid/vendor/trix/src/trix/config/css.coffee +12 -0
  273. data/lib/vapid/vendor/trix/src/trix/config/file_size_formatting.coffee +22 -0
  274. data/lib/vapid/vendor/trix/src/trix/config/index.coffee +9 -0
  275. data/lib/vapid/vendor/trix/src/trix/config/lang.coffee +26 -0
  276. data/lib/vapid/vendor/trix/src/trix/config/selection_elements.coffee +26 -0
  277. data/lib/vapid/vendor/trix/src/trix/config/serialization.coffee +63 -0
  278. data/lib/vapid/vendor/trix/src/trix/config/text_attributes.coffee +25 -0
  279. data/lib/vapid/vendor/trix/src/trix/config/toolbar.coffee +41 -0
  280. data/lib/vapid/vendor/trix/src/trix/config/undo_interval.coffee +7 -0
  281. data/lib/vapid/vendor/trix/src/trix/controllers/attachment_editor_controller.coffee +104 -0
  282. data/lib/vapid/vendor/trix/src/trix/controllers/composition_controller.coffee +117 -0
  283. data/lib/vapid/vendor/trix/src/trix/controllers/controller.coffee +3 -0
  284. data/lib/vapid/vendor/trix/src/trix/controllers/editor_controller.coffee +369 -0
  285. data/lib/vapid/vendor/trix/src/trix/controllers/input/composition_input.coffee +57 -0
  286. data/lib/vapid/vendor/trix/src/trix/controllers/input_controller.coffee +473 -0
  287. data/lib/vapid/vendor/trix/src/trix/controllers/toolbar_controller.coffee +173 -0
  288. data/lib/vapid/vendor/trix/src/trix/core/basic_object.coffee +44 -0
  289. data/lib/vapid/vendor/trix/src/trix/core/collections/element_store.coffee +21 -0
  290. data/lib/vapid/vendor/trix/src/trix/core/collections/hash.coffee +98 -0
  291. data/lib/vapid/vendor/trix/src/trix/core/collections/index.coffee +4 -0
  292. data/lib/vapid/vendor/trix/src/trix/core/collections/object_group.coffee +37 -0
  293. data/lib/vapid/vendor/trix/src/trix/core/collections/object_map.coffee +10 -0
  294. data/lib/vapid/vendor/trix/src/trix/core/helpers/arrays.coffee +34 -0
  295. data/lib/vapid/vendor/trix/src/trix/core/helpers/config.coffee +23 -0
  296. data/lib/vapid/vendor/trix/src/trix/core/helpers/custom_elements.coffee +45 -0
  297. data/lib/vapid/vendor/trix/src/trix/core/helpers/dom.coffee +185 -0
  298. data/lib/vapid/vendor/trix/src/trix/core/helpers/extend.coffee +4 -0
  299. data/lib/vapid/vendor/trix/src/trix/core/helpers/functions.coffee +3 -0
  300. data/lib/vapid/vendor/trix/src/trix/core/helpers/global.coffee +23 -0
  301. data/lib/vapid/vendor/trix/src/trix/core/helpers/index.coffee +10 -0
  302. data/lib/vapid/vendor/trix/src/trix/core/helpers/objects.coffee +11 -0
  303. data/lib/vapid/vendor/trix/src/trix/core/helpers/ranges.coffee +33 -0
  304. data/lib/vapid/vendor/trix/src/trix/core/helpers/selection.coffee +25 -0
  305. data/lib/vapid/vendor/trix/src/trix/core/helpers/strings.coffee +46 -0
  306. data/lib/vapid/vendor/trix/src/trix/core/index.coffee +4 -0
  307. data/lib/vapid/vendor/trix/src/trix/core/object.coffee +33 -0
  308. data/lib/vapid/vendor/trix/src/trix/core/utilities/index.coffee +2 -0
  309. data/lib/vapid/vendor/trix/src/trix/core/utilities/operation.coffee +37 -0
  310. data/lib/vapid/vendor/trix/src/trix/core/utilities/utf16_string.coffee +93 -0
  311. data/lib/vapid/vendor/trix/src/trix/elements/trix_editor_element.coffee +166 -0
  312. data/lib/vapid/vendor/trix/src/trix/elements/trix_toolbar_element.coffee +28 -0
  313. data/lib/vapid/vendor/trix/src/trix/index.coffee.erb +14 -0
  314. data/lib/vapid/vendor/trix/src/trix/inspector/control_element.coffee +60 -0
  315. data/lib/vapid/vendor/trix/src/trix/inspector/debugger.coffee +104 -0
  316. data/lib/vapid/vendor/trix/src/trix/inspector/element.coffee +86 -0
  317. data/lib/vapid/vendor/trix/src/trix/inspector/index.coffee +17 -0
  318. data/lib/vapid/vendor/trix/src/trix/inspector/polyfills/vendor/details-element-polyfill.js +5 -0
  319. data/lib/vapid/vendor/trix/src/trix/inspector/templates/debug.jst.eco +17 -0
  320. data/lib/vapid/vendor/trix/src/trix/inspector/templates/document.jst.eco +33 -0
  321. data/lib/vapid/vendor/trix/src/trix/inspector/templates/performance.jst.eco +10 -0
  322. data/lib/vapid/vendor/trix/src/trix/inspector/templates/render.jst.eco +1 -0
  323. data/lib/vapid/vendor/trix/src/trix/inspector/templates/selection.jst.eco +5 -0
  324. data/lib/vapid/vendor/trix/src/trix/inspector/templates/undo.jst.eco +13 -0
  325. data/lib/vapid/vendor/trix/src/trix/inspector/view.coffee +58 -0
  326. data/lib/vapid/vendor/trix/src/trix/inspector/views/debug_view.coffee +33 -0
  327. data/lib/vapid/vendor/trix/src/trix/inspector/views/document_view.coffee +12 -0
  328. data/lib/vapid/vendor/trix/src/trix/inspector/views/performance_view.coffee +51 -0
  329. data/lib/vapid/vendor/trix/src/trix/inspector/views/render_view.coffee +21 -0
  330. data/lib/vapid/vendor/trix/src/trix/inspector/views/selection_view.coffee +33 -0
  331. data/lib/vapid/vendor/trix/src/trix/inspector/views/undo_view.coffee +12 -0
  332. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/deserializer.coffee +55 -0
  333. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/index.coffee +5 -0
  334. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/player.coffee +60 -0
  335. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/player_controller.coffee +43 -0
  336. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/player_element.coffee +32 -0
  337. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/player_view.coffee +133 -0
  338. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/recorder.coffee +82 -0
  339. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/recording.coffee +54 -0
  340. data/lib/vapid/vendor/trix/src/trix/inspector/watchdog/serializer.coffee +61 -0
  341. data/lib/vapid/vendor/trix/src/trix/models/attachment.coffee +157 -0
  342. data/lib/vapid/vendor/trix/src/trix/models/attachment_manager.coffee +24 -0
  343. data/lib/vapid/vendor/trix/src/trix/models/attachment_piece.coffee +47 -0
  344. data/lib/vapid/vendor/trix/src/trix/models/block.coffee +230 -0
  345. data/lib/vapid/vendor/trix/src/trix/models/composition.coffee +521 -0
  346. data/lib/vapid/vendor/trix/src/trix/models/document.coffee +538 -0
  347. data/lib/vapid/vendor/trix/src/trix/models/editor.coffee +141 -0
  348. data/lib/vapid/vendor/trix/src/trix/models/html_parser.coffee +335 -0
  349. data/lib/vapid/vendor/trix/src/trix/models/line_break_insertion.coffee +31 -0
  350. data/lib/vapid/vendor/trix/src/trix/models/location_mapper.coffee +156 -0
  351. data/lib/vapid/vendor/trix/src/trix/models/managed_attachment.coffee +28 -0
  352. data/lib/vapid/vendor/trix/src/trix/models/piece.coffee +95 -0
  353. data/lib/vapid/vendor/trix/src/trix/models/point_mapper.coffee +28 -0
  354. data/lib/vapid/vendor/trix/src/trix/models/selection_manager.coffee +129 -0
  355. data/lib/vapid/vendor/trix/src/trix/models/splittable_list.coffee +168 -0
  356. data/lib/vapid/vendor/trix/src/trix/models/string_piece.coffee +49 -0
  357. data/lib/vapid/vendor/trix/src/trix/models/text.coffee +168 -0
  358. data/lib/vapid/vendor/trix/src/trix/models/undo_manager.coffee +40 -0
  359. data/lib/vapid/vendor/trix/src/trix/observers/mutation_observer.coffee +131 -0
  360. data/lib/vapid/vendor/trix/src/trix/observers/selection_change_observer.coffee +56 -0
  361. data/lib/vapid/vendor/trix/src/trix/operations/file_verification_operation.coffee +15 -0
  362. data/lib/vapid/vendor/trix/src/trix/operations/image_preload_operation.coffee +15 -0
  363. data/lib/vapid/vendor/trix/src/trix/views/attachment_view.coffee +99 -0
  364. data/lib/vapid/vendor/trix/src/trix/views/block_view.coffee +37 -0
  365. data/lib/vapid/vendor/trix/src/trix/views/document_view.coffee +68 -0
  366. data/lib/vapid/vendor/trix/src/trix/views/object_group_view.coffee +23 -0
  367. data/lib/vapid/vendor/trix/src/trix/views/object_view.coffee +86 -0
  368. data/lib/vapid/vendor/trix/src/trix/views/piece_view.coffee +97 -0
  369. data/lib/vapid/vendor/trix/src/trix/views/previewable_attachment_view.coffee +49 -0
  370. data/lib/vapid/vendor/trix/src/trix/views/text_view.coffee +30 -0
  371. data/lib/vapid/vendor/trix/test/.gitignore +1 -0
  372. data/lib/vapid/vendor/trix/test/src/system/attachment_test.coffee +70 -0
  373. data/lib/vapid/vendor/trix/test/src/system/basic_input_test.coffee +68 -0
  374. data/lib/vapid/vendor/trix/test/src/system/block_formatting_test.coffee +602 -0
  375. data/lib/vapid/vendor/trix/test/src/system/caching_test.coffee +21 -0
  376. data/lib/vapid/vendor/trix/test/src/system/composition_input_test.coffee +138 -0
  377. data/lib/vapid/vendor/trix/test/src/system/cursor_movement_test.coffee +54 -0
  378. data/lib/vapid/vendor/trix/test/src/system/custom_element_test.coffee +314 -0
  379. data/lib/vapid/vendor/trix/test/src/system/html_loading_test.coffee +62 -0
  380. data/lib/vapid/vendor/trix/test/src/system/html_replacement_test.coffee +101 -0
  381. data/lib/vapid/vendor/trix/test/src/system/installation_process_test.coffee +59 -0
  382. data/lib/vapid/vendor/trix/test/src/system/list_formatting_test.coffee +70 -0
  383. data/lib/vapid/vendor/trix/test/src/system/mutation_input_test.coffee +73 -0
  384. data/lib/vapid/vendor/trix/test/src/system/pasting_test.coffee +215 -0
  385. data/lib/vapid/vendor/trix/test/src/system/text_formatting_test.coffee +151 -0
  386. data/lib/vapid/vendor/trix/test/src/system/undo_test.coffee +48 -0
  387. data/lib/vapid/vendor/trix/test/src/test.coffee +16 -0
  388. data/lib/vapid/vendor/trix/test/src/test_helpers/assertions.coffee +38 -0
  389. data/lib/vapid/vendor/trix/test/src/test_helpers/editor_helpers.coffee +37 -0
  390. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_empty.jst.eco +1 -0
  391. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_html.jst.eco +2 -0
  392. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_in_table.jst.eco +7 -0
  393. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_with_block_styles.jst.eco +6 -0
  394. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_with_bold_styles.jst.eco +7 -0
  395. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_with_image.jst.eco +2 -0
  396. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_with_styled_content.jst.eco +7 -0
  397. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/editor_with_toolbar_and_input.jst.eco +5 -0
  398. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/fixtures.coffee +536 -0
  399. data/lib/vapid/vendor/trix/test/src/test_helpers/fixtures/logo.png +0 -0
  400. data/lib/vapid/vendor/trix/test/src/test_helpers/index.coffee +18 -0
  401. data/lib/vapid/vendor/trix/test/src/test_helpers/input_helpers.coffee +183 -0
  402. data/lib/vapid/vendor/trix/test/src/test_helpers/selection_helpers.coffee +91 -0
  403. data/lib/vapid/vendor/trix/test/src/test_helpers/test_helpers.coffee +72 -0
  404. data/lib/vapid/vendor/trix/test/src/test_helpers/test_stubs.coffee +31 -0
  405. data/lib/vapid/vendor/trix/test/src/test_helpers/toolbar_helpers.coffee +45 -0
  406. data/lib/vapid/vendor/trix/test/src/unit/attachment_test.coffee +23 -0
  407. data/lib/vapid/vendor/trix/test/src/unit/block_test.coffee +22 -0
  408. data/lib/vapid/vendor/trix/test/src/unit/composition_test.coffee +13 -0
  409. data/lib/vapid/vendor/trix/test/src/unit/document_test.coffee +11 -0
  410. data/lib/vapid/vendor/trix/test/src/unit/document_view_test.coffee +6 -0
  411. data/lib/vapid/vendor/trix/test/src/unit/html_parser_test.coffee +162 -0
  412. data/lib/vapid/vendor/trix/test/src/unit/location_mapper_test.coffee +185 -0
  413. data/lib/vapid/vendor/trix/test/src/unit/mutation_observer_test.coffee +84 -0
  414. data/lib/vapid/vendor/trix/test/src/unit/serialization_test.coffee +7 -0
  415. data/lib/vapid/vendor/trix/test/src/unit/string_change_summary_test.coffee +57 -0
  416. data/lib/vapid/vendor/trix/test/src/unit/text_test.coffee +19 -0
  417. data/lib/vapid/vendor/trix/test/vendor/rangy-core.js +3845 -0
  418. data/lib/vapid/vendor/trix/test/vendor/rangy-textrange.js +1930 -0
  419. data/lib/vapid/version.rb +4 -0
  420. data/lib/vapid/views/admin/install.html.erb +19 -0
  421. data/lib/vapid/views/admin/login.html.erb +11 -0
  422. data/lib/vapid/views/admin/overview/index.html.erb +1 -0
  423. data/lib/vapid/views/admin/records/_form.erb +9 -0
  424. data/lib/vapid/views/admin/records/edit.html.erb +5 -0
  425. data/lib/vapid/views/admin/records/index.html.erb +38 -0
  426. data/lib/vapid/views/admin/records/new.html.erb +3 -0
  427. data/lib/vapid/views/errors/404.html.erb +1 -0
  428. data/lib/vapid/views/errors/500.html.erb +1 -0
  429. data/lib/vapid/views/layouts/admin.html.erb +41 -0
  430. data/lib/vapid/views/layouts/admin_form.html.erb +22 -0
  431. data/lib/vapid/views/layouts/error.html.erb +11 -0
  432. data/vapid.gemspec +48 -0
  433. metadata +811 -0
@@ -0,0 +1,1442 @@
1
+ /*!
2
+ * # Semantic UI 2.2.9 - Search
3
+ * http://github.com/semantic-org/semantic-ui/
4
+ *
5
+ *
6
+ * Released under the MIT license
7
+ * http://opensource.org/licenses/MIT
8
+ *
9
+ */
10
+
11
+ ;(function ($, window, document, undefined) {
12
+
13
+ "use strict";
14
+
15
+ window = (typeof window != 'undefined' && window.Math == Math)
16
+ ? window
17
+ : (typeof self != 'undefined' && self.Math == Math)
18
+ ? self
19
+ : Function('return this')()
20
+ ;
21
+
22
+ $.fn.search = function(parameters) {
23
+ var
24
+ $allModules = $(this),
25
+ moduleSelector = $allModules.selector || '',
26
+
27
+ time = new Date().getTime(),
28
+ performance = [],
29
+
30
+ query = arguments[0],
31
+ methodInvoked = (typeof query == 'string'),
32
+ queryArguments = [].slice.call(arguments, 1),
33
+ returnedValue
34
+ ;
35
+ $(this)
36
+ .each(function() {
37
+ var
38
+ settings = ( $.isPlainObject(parameters) )
39
+ ? $.extend(true, {}, $.fn.search.settings, parameters)
40
+ : $.extend({}, $.fn.search.settings),
41
+
42
+ className = settings.className,
43
+ metadata = settings.metadata,
44
+ regExp = settings.regExp,
45
+ fields = settings.fields,
46
+ selector = settings.selector,
47
+ error = settings.error,
48
+ namespace = settings.namespace,
49
+
50
+ eventNamespace = '.' + namespace,
51
+ moduleNamespace = namespace + '-module',
52
+
53
+ $module = $(this),
54
+ $prompt = $module.find(selector.prompt),
55
+ $searchButton = $module.find(selector.searchButton),
56
+ $results = $module.find(selector.results),
57
+ $result = $module.find(selector.result),
58
+ $category = $module.find(selector.category),
59
+
60
+ element = this,
61
+ instance = $module.data(moduleNamespace),
62
+
63
+ disabledBubbled = false,
64
+ resultsDismissed = false,
65
+
66
+ module
67
+ ;
68
+
69
+ module = {
70
+
71
+ initialize: function() {
72
+ module.verbose('Initializing module');
73
+ module.determine.searchFields();
74
+ module.bind.events();
75
+ module.set.type();
76
+ module.create.results();
77
+ module.instantiate();
78
+ },
79
+ instantiate: function() {
80
+ module.verbose('Storing instance of module', module);
81
+ instance = module;
82
+ $module
83
+ .data(moduleNamespace, module)
84
+ ;
85
+ },
86
+ destroy: function() {
87
+ module.verbose('Destroying instance');
88
+ $module
89
+ .off(eventNamespace)
90
+ .removeData(moduleNamespace)
91
+ ;
92
+ },
93
+
94
+ refresh: function() {
95
+ module.debug('Refreshing selector cache');
96
+ $prompt = $module.find(selector.prompt);
97
+ $searchButton = $module.find(selector.searchButton);
98
+ $category = $module.find(selector.category);
99
+ $results = $module.find(selector.results);
100
+ $result = $module.find(selector.result);
101
+ },
102
+
103
+ refreshResults: function() {
104
+ $results = $module.find(selector.results);
105
+ $result = $module.find(selector.result);
106
+ },
107
+
108
+ bind: {
109
+ events: function() {
110
+ module.verbose('Binding events to search');
111
+ if(settings.automatic) {
112
+ $module
113
+ .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input)
114
+ ;
115
+ $prompt
116
+ .attr('autocomplete', 'off')
117
+ ;
118
+ }
119
+ $module
120
+ // prompt
121
+ .on('focus' + eventNamespace, selector.prompt, module.event.focus)
122
+ .on('blur' + eventNamespace, selector.prompt, module.event.blur)
123
+ .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard)
124
+ // search button
125
+ .on('click' + eventNamespace, selector.searchButton, module.query)
126
+ // results
127
+ .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown)
128
+ .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup)
129
+ .on('click' + eventNamespace, selector.result, module.event.result.click)
130
+ ;
131
+ }
132
+ },
133
+
134
+ determine: {
135
+ searchFields: function() {
136
+ // this makes sure $.extend does not add specified search fields to default fields
137
+ // this is the only setting which should not extend defaults
138
+ if(parameters && parameters.searchFields !== undefined) {
139
+ settings.searchFields = parameters.searchFields;
140
+ }
141
+ }
142
+ },
143
+
144
+ event: {
145
+ input: function() {
146
+ clearTimeout(module.timer);
147
+ module.timer = setTimeout(module.query, settings.searchDelay);
148
+ },
149
+ focus: function() {
150
+ module.set.focus();
151
+ if(settings.searchOnFocus && module.has.minimumCharacters() ) {
152
+ module.query(function() {
153
+ if(module.can.show() ) {
154
+ module.showResults();
155
+ }
156
+ });
157
+ }
158
+ },
159
+ blur: function(event) {
160
+ var
161
+ pageLostFocus = (document.activeElement === this),
162
+ callback = function() {
163
+ module.cancel.query();
164
+ module.remove.focus();
165
+ module.timer = setTimeout(module.hideResults, settings.hideDelay);
166
+ }
167
+ ;
168
+ if(pageLostFocus) {
169
+ return;
170
+ }
171
+ resultsDismissed = false;
172
+ if(module.resultsClicked) {
173
+ module.debug('Determining if user action caused search to close');
174
+ $module
175
+ .one('click.close' + eventNamespace, selector.results, function(event) {
176
+ if(module.is.inMessage(event) || disabledBubbled) {
177
+ $prompt.focus();
178
+ return;
179
+ }
180
+ disabledBubbled = false;
181
+ if( !module.is.animating() && !module.is.hidden()) {
182
+ callback();
183
+ }
184
+ })
185
+ ;
186
+ }
187
+ else {
188
+ module.debug('Input blurred without user action, closing results');
189
+ callback();
190
+ }
191
+ },
192
+ result: {
193
+ mousedown: function() {
194
+ module.resultsClicked = true;
195
+ },
196
+ mouseup: function() {
197
+ module.resultsClicked = false;
198
+ },
199
+ click: function(event) {
200
+ module.debug('Search result selected');
201
+ var
202
+ $result = $(this),
203
+ $title = $result.find(selector.title).eq(0),
204
+ $link = $result.is('a[href]')
205
+ ? $result
206
+ : $result.find('a[href]').eq(0),
207
+ href = $link.attr('href') || false,
208
+ target = $link.attr('target') || false,
209
+ title = $title.html(),
210
+ // title is used for result lookup
211
+ value = ($title.length > 0)
212
+ ? $title.text()
213
+ : false,
214
+ results = module.get.results(),
215
+ result = $result.data(metadata.result) || module.get.result(value, results),
216
+ returnedValue
217
+ ;
218
+ if( $.isFunction(settings.onSelect) ) {
219
+ if(settings.onSelect.call(element, result, results) === false) {
220
+ module.debug('Custom onSelect callback cancelled default select action');
221
+ disabledBubbled = true;
222
+ return;
223
+ }
224
+ }
225
+ module.hideResults();
226
+ if(value) {
227
+ module.set.value(value);
228
+ }
229
+ if(href) {
230
+ module.verbose('Opening search link found in result', $link);
231
+ if(target == '_blank' || event.ctrlKey) {
232
+ window.open(href);
233
+ }
234
+ else {
235
+ window.location.href = (href);
236
+ }
237
+ }
238
+ }
239
+ }
240
+ },
241
+ handleKeyboard: function(event) {
242
+ var
243
+ // force selector refresh
244
+ $result = $module.find(selector.result),
245
+ $category = $module.find(selector.category),
246
+ $activeResult = $result.filter('.' + className.active),
247
+ currentIndex = $result.index( $activeResult ),
248
+ resultSize = $result.length,
249
+ hasActiveResult = $activeResult.length > 0,
250
+
251
+ keyCode = event.which,
252
+ keys = {
253
+ backspace : 8,
254
+ enter : 13,
255
+ escape : 27,
256
+ upArrow : 38,
257
+ downArrow : 40
258
+ },
259
+ newIndex
260
+ ;
261
+ // search shortcuts
262
+ if(keyCode == keys.escape) {
263
+ module.verbose('Escape key pressed, blurring search field');
264
+ module.hideResults();
265
+ resultsDismissed = true;
266
+ }
267
+ if( module.is.visible() ) {
268
+ if(keyCode == keys.enter) {
269
+ module.verbose('Enter key pressed, selecting active result');
270
+ if( $result.filter('.' + className.active).length > 0 ) {
271
+ module.event.result.click.call($result.filter('.' + className.active), event);
272
+ event.preventDefault();
273
+ return false;
274
+ }
275
+ }
276
+ else if(keyCode == keys.upArrow && hasActiveResult) {
277
+ module.verbose('Up key pressed, changing active result');
278
+ newIndex = (currentIndex - 1 < 0)
279
+ ? currentIndex
280
+ : currentIndex - 1
281
+ ;
282
+ $category
283
+ .removeClass(className.active)
284
+ ;
285
+ $result
286
+ .removeClass(className.active)
287
+ .eq(newIndex)
288
+ .addClass(className.active)
289
+ .closest($category)
290
+ .addClass(className.active)
291
+ ;
292
+ event.preventDefault();
293
+ }
294
+ else if(keyCode == keys.downArrow) {
295
+ module.verbose('Down key pressed, changing active result');
296
+ newIndex = (currentIndex + 1 >= resultSize)
297
+ ? currentIndex
298
+ : currentIndex + 1
299
+ ;
300
+ $category
301
+ .removeClass(className.active)
302
+ ;
303
+ $result
304
+ .removeClass(className.active)
305
+ .eq(newIndex)
306
+ .addClass(className.active)
307
+ .closest($category)
308
+ .addClass(className.active)
309
+ ;
310
+ event.preventDefault();
311
+ }
312
+ }
313
+ else {
314
+ // query shortcuts
315
+ if(keyCode == keys.enter) {
316
+ module.verbose('Enter key pressed, executing query');
317
+ module.query();
318
+ module.set.buttonPressed();
319
+ $prompt.one('keyup', module.remove.buttonFocus);
320
+ }
321
+ }
322
+ },
323
+
324
+ setup: {
325
+ api: function(searchTerm, callback) {
326
+ var
327
+ apiSettings = {
328
+ debug : settings.debug,
329
+ on : false,
330
+ cache : true,
331
+ action : 'search',
332
+ urlData : {
333
+ query : searchTerm
334
+ },
335
+ onSuccess : function(response) {
336
+ module.parse.response.call(element, response, searchTerm);
337
+ callback();
338
+ },
339
+ onFailure : function() {
340
+ module.displayMessage(error.serverError);
341
+ callback();
342
+ },
343
+ onAbort : function(response) {
344
+ },
345
+ onError : module.error
346
+ },
347
+ searchHTML
348
+ ;
349
+ $.extend(true, apiSettings, settings.apiSettings);
350
+ module.verbose('Setting up API request', apiSettings);
351
+ $module.api(apiSettings);
352
+ }
353
+ },
354
+
355
+ can: {
356
+ useAPI: function() {
357
+ return $.fn.api !== undefined;
358
+ },
359
+ show: function() {
360
+ return module.is.focused() && !module.is.visible() && !module.is.empty();
361
+ },
362
+ transition: function() {
363
+ return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
364
+ }
365
+ },
366
+
367
+ is: {
368
+ animating: function() {
369
+ return $results.hasClass(className.animating);
370
+ },
371
+ hidden: function() {
372
+ return $results.hasClass(className.hidden);
373
+ },
374
+ inMessage: function(event) {
375
+ if(!event.target) {
376
+ return;
377
+ }
378
+ var
379
+ $target = $(event.target),
380
+ isInDOM = $.contains(document.documentElement, event.target)
381
+ ;
382
+ return (isInDOM && $target.closest(selector.message).length > 0);
383
+ },
384
+ empty: function() {
385
+ return ($results.html() === '');
386
+ },
387
+ visible: function() {
388
+ return ($results.filter(':visible').length > 0);
389
+ },
390
+ focused: function() {
391
+ return ($prompt.filter(':focus').length > 0);
392
+ }
393
+ },
394
+
395
+ get: {
396
+ inputEvent: function() {
397
+ var
398
+ prompt = $prompt[0],
399
+ inputEvent = (prompt !== undefined && prompt.oninput !== undefined)
400
+ ? 'input'
401
+ : (prompt !== undefined && prompt.onpropertychange !== undefined)
402
+ ? 'propertychange'
403
+ : 'keyup'
404
+ ;
405
+ return inputEvent;
406
+ },
407
+ value: function() {
408
+ return $prompt.val();
409
+ },
410
+ results: function() {
411
+ var
412
+ results = $module.data(metadata.results)
413
+ ;
414
+ return results;
415
+ },
416
+ result: function(value, results) {
417
+ var
418
+ lookupFields = ['title', 'id'],
419
+ result = false
420
+ ;
421
+ value = (value !== undefined)
422
+ ? value
423
+ : module.get.value()
424
+ ;
425
+ results = (results !== undefined)
426
+ ? results
427
+ : module.get.results()
428
+ ;
429
+ if(settings.type === 'category') {
430
+ module.debug('Finding result that matches', value);
431
+ $.each(results, function(index, category) {
432
+ if($.isArray(category.results)) {
433
+ result = module.search.object(value, category.results, lookupFields)[0];
434
+ // don't continue searching if a result is found
435
+ if(result) {
436
+ return false;
437
+ }
438
+ }
439
+ });
440
+ }
441
+ else {
442
+ module.debug('Finding result in results object', value);
443
+ result = module.search.object(value, results, lookupFields)[0];
444
+ }
445
+ return result || false;
446
+ },
447
+ },
448
+
449
+ select: {
450
+ firstResult: function() {
451
+ module.verbose('Selecting first result');
452
+ $result.first().addClass(className.active);
453
+ }
454
+ },
455
+
456
+ set: {
457
+ focus: function() {
458
+ $module.addClass(className.focus);
459
+ },
460
+ loading: function() {
461
+ $module.addClass(className.loading);
462
+ },
463
+ value: function(value) {
464
+ module.verbose('Setting search input value', value);
465
+ $prompt
466
+ .val(value)
467
+ ;
468
+ },
469
+ type: function(type) {
470
+ type = type || settings.type;
471
+ if(settings.type == 'category') {
472
+ $module.addClass(settings.type);
473
+ }
474
+ },
475
+ buttonPressed: function() {
476
+ $searchButton.addClass(className.pressed);
477
+ }
478
+ },
479
+
480
+ remove: {
481
+ loading: function() {
482
+ $module.removeClass(className.loading);
483
+ },
484
+ focus: function() {
485
+ $module.removeClass(className.focus);
486
+ },
487
+ buttonPressed: function() {
488
+ $searchButton.removeClass(className.pressed);
489
+ }
490
+ },
491
+
492
+ query: function(callback) {
493
+ callback = $.isFunction(callback)
494
+ ? callback
495
+ : function(){}
496
+ ;
497
+ var
498
+ searchTerm = module.get.value(),
499
+ cache = module.read.cache(searchTerm)
500
+ ;
501
+ callback = callback || function() {};
502
+ if( module.has.minimumCharacters() ) {
503
+ if(cache) {
504
+ module.debug('Reading result from cache', searchTerm);
505
+ module.save.results(cache.results);
506
+ module.addResults(cache.html);
507
+ module.inject.id(cache.results);
508
+ callback();
509
+ }
510
+ else {
511
+ module.debug('Querying for', searchTerm);
512
+ if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
513
+ module.search.local(searchTerm);
514
+ callback();
515
+ }
516
+ else if( module.can.useAPI() ) {
517
+ module.search.remote(searchTerm, callback);
518
+ }
519
+ else {
520
+ module.error(error.source);
521
+ callback();
522
+ }
523
+ }
524
+ settings.onSearchQuery.call(element, searchTerm);
525
+ }
526
+ else {
527
+ module.hideResults();
528
+ }
529
+ },
530
+
531
+ search: {
532
+ local: function(searchTerm) {
533
+ var
534
+ results = module.search.object(searchTerm, settings.content),
535
+ searchHTML
536
+ ;
537
+ module.set.loading();
538
+ module.save.results(results);
539
+ module.debug('Returned local search results', results);
540
+
541
+ searchHTML = module.generateResults({
542
+ results: results
543
+ });
544
+ module.remove.loading();
545
+ module.addResults(searchHTML);
546
+ module.inject.id(results);
547
+ module.write.cache(searchTerm, {
548
+ html : searchHTML,
549
+ results : results
550
+ });
551
+ },
552
+ remote: function(searchTerm, callback) {
553
+ callback = $.isFunction(callback)
554
+ ? callback
555
+ : function(){}
556
+ ;
557
+ if($module.api('is loading')) {
558
+ $module.api('abort');
559
+ }
560
+ module.setup.api(searchTerm, callback);
561
+ $module
562
+ .api('query')
563
+ ;
564
+ },
565
+ object: function(searchTerm, source, searchFields) {
566
+ var
567
+ results = [],
568
+ fuzzyResults = [],
569
+ searchExp = searchTerm.toString().replace(regExp.escape, '\\$&'),
570
+ matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'),
571
+
572
+ // avoid duplicates when pushing results
573
+ addResult = function(array, result) {
574
+ var
575
+ notResult = ($.inArray(result, results) == -1),
576
+ notFuzzyResult = ($.inArray(result, fuzzyResults) == -1)
577
+ ;
578
+ if(notResult && notFuzzyResult) {
579
+ array.push(result);
580
+ }
581
+ }
582
+ ;
583
+ source = source || settings.source;
584
+ searchFields = (searchFields !== undefined)
585
+ ? searchFields
586
+ : settings.searchFields
587
+ ;
588
+
589
+ // search fields should be array to loop correctly
590
+ if(!$.isArray(searchFields)) {
591
+ searchFields = [searchFields];
592
+ }
593
+
594
+ // exit conditions if no source
595
+ if(source === undefined || source === false) {
596
+ module.error(error.source);
597
+ return [];
598
+ }
599
+
600
+ // iterate through search fields looking for matches
601
+ $.each(searchFields, function(index, field) {
602
+ $.each(source, function(label, content) {
603
+ var
604
+ fieldExists = (typeof content[field] == 'string')
605
+ ;
606
+ if(fieldExists) {
607
+ if( content[field].search(matchRegExp) !== -1) {
608
+ // content starts with value (first in results)
609
+ addResult(results, content);
610
+ }
611
+ else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
612
+ // content fuzzy matches (last in results)
613
+ addResult(fuzzyResults, content);
614
+ }
615
+ }
616
+ });
617
+ });
618
+ return $.merge(results, fuzzyResults);
619
+ }
620
+ },
621
+
622
+ fuzzySearch: function(query, term) {
623
+ var
624
+ termLength = term.length,
625
+ queryLength = query.length
626
+ ;
627
+ if(typeof query !== 'string') {
628
+ return false;
629
+ }
630
+ query = query.toLowerCase();
631
+ term = term.toLowerCase();
632
+ if(queryLength > termLength) {
633
+ return false;
634
+ }
635
+ if(queryLength === termLength) {
636
+ return (query === term);
637
+ }
638
+ search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
639
+ var
640
+ queryCharacter = query.charCodeAt(characterIndex)
641
+ ;
642
+ while(nextCharacterIndex < termLength) {
643
+ if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
644
+ continue search;
645
+ }
646
+ }
647
+ return false;
648
+ }
649
+ return true;
650
+ },
651
+
652
+ parse: {
653
+ response: function(response, searchTerm) {
654
+ var
655
+ searchHTML = module.generateResults(response)
656
+ ;
657
+ module.verbose('Parsing server response', response);
658
+ if(response !== undefined) {
659
+ if(searchTerm !== undefined && response[fields.results] !== undefined) {
660
+ module.addResults(searchHTML);
661
+ module.inject.id(response[fields.results]);
662
+ module.write.cache(searchTerm, {
663
+ html : searchHTML,
664
+ results : response[fields.results]
665
+ });
666
+ module.save.results(response[fields.results]);
667
+ }
668
+ }
669
+ }
670
+ },
671
+
672
+ cancel: {
673
+ query: function() {
674
+ if( module.can.useAPI() ) {
675
+ $module.api('abort');
676
+ }
677
+ }
678
+ },
679
+
680
+ has: {
681
+ minimumCharacters: function() {
682
+ var
683
+ searchTerm = module.get.value(),
684
+ numCharacters = searchTerm.length
685
+ ;
686
+ return (numCharacters >= settings.minCharacters);
687
+ },
688
+ results: function() {
689
+ if($results.length === 0) {
690
+ return false;
691
+ }
692
+ var
693
+ html = $results.html()
694
+ ;
695
+ return html != '';
696
+ }
697
+ },
698
+
699
+ clear: {
700
+ cache: function(value) {
701
+ var
702
+ cache = $module.data(metadata.cache)
703
+ ;
704
+ if(!value) {
705
+ module.debug('Clearing cache', value);
706
+ $module.removeData(metadata.cache);
707
+ }
708
+ else if(value && cache && cache[value]) {
709
+ module.debug('Removing value from cache', value);
710
+ delete cache[value];
711
+ $module.data(metadata.cache, cache);
712
+ }
713
+ }
714
+ },
715
+
716
+ read: {
717
+ cache: function(name) {
718
+ var
719
+ cache = $module.data(metadata.cache)
720
+ ;
721
+ if(settings.cache) {
722
+ module.verbose('Checking cache for generated html for query', name);
723
+ return (typeof cache == 'object') && (cache[name] !== undefined)
724
+ ? cache[name]
725
+ : false
726
+ ;
727
+ }
728
+ return false;
729
+ }
730
+ },
731
+
732
+ create: {
733
+ id: function(resultIndex, categoryIndex) {
734
+ var
735
+ resultID = (resultIndex + 1), // not zero indexed
736
+ categoryID = (categoryIndex + 1),
737
+ firstCharCode,
738
+ letterID,
739
+ id
740
+ ;
741
+ if(categoryIndex !== undefined) {
742
+ // start char code for "A"
743
+ letterID = String.fromCharCode(97 + categoryIndex);
744
+ id = letterID + resultID;
745
+ module.verbose('Creating category result id', id);
746
+ }
747
+ else {
748
+ id = resultID;
749
+ module.verbose('Creating result id', id);
750
+ }
751
+ return id;
752
+ },
753
+ results: function() {
754
+ if($results.length === 0) {
755
+ $results = $('<div />')
756
+ .addClass(className.results)
757
+ .appendTo($module)
758
+ ;
759
+ }
760
+ }
761
+ },
762
+
763
+ inject: {
764
+ result: function(result, resultIndex, categoryIndex) {
765
+ module.verbose('Injecting result into results');
766
+ var
767
+ $selectedResult = (categoryIndex !== undefined)
768
+ ? $results
769
+ .children().eq(categoryIndex)
770
+ .children(selector.result).eq(resultIndex)
771
+ : $results
772
+ .children(selector.result).eq(resultIndex)
773
+ ;
774
+ module.verbose('Injecting results metadata', $selectedResult);
775
+ $selectedResult
776
+ .data(metadata.result, result)
777
+ ;
778
+ },
779
+ id: function(results) {
780
+ module.debug('Injecting unique ids into results');
781
+ var
782
+ // since results may be object, we must use counters
783
+ categoryIndex = 0,
784
+ resultIndex = 0
785
+ ;
786
+ if(settings.type === 'category') {
787
+ // iterate through each category result
788
+ $.each(results, function(index, category) {
789
+ resultIndex = 0;
790
+ $.each(category.results, function(index, value) {
791
+ var
792
+ result = category.results[index]
793
+ ;
794
+ if(result.id === undefined) {
795
+ result.id = module.create.id(resultIndex, categoryIndex);
796
+ }
797
+ module.inject.result(result, resultIndex, categoryIndex);
798
+ resultIndex++;
799
+ });
800
+ categoryIndex++;
801
+ });
802
+ }
803
+ else {
804
+ // top level
805
+ $.each(results, function(index, value) {
806
+ var
807
+ result = results[index]
808
+ ;
809
+ if(result.id === undefined) {
810
+ result.id = module.create.id(resultIndex);
811
+ }
812
+ module.inject.result(result, resultIndex);
813
+ resultIndex++;
814
+ });
815
+ }
816
+ return results;
817
+ }
818
+ },
819
+
820
+ save: {
821
+ results: function(results) {
822
+ module.verbose('Saving current search results to metadata', results);
823
+ $module.data(metadata.results, results);
824
+ }
825
+ },
826
+
827
+ write: {
828
+ cache: function(name, value) {
829
+ var
830
+ cache = ($module.data(metadata.cache) !== undefined)
831
+ ? $module.data(metadata.cache)
832
+ : {}
833
+ ;
834
+ if(settings.cache) {
835
+ module.verbose('Writing generated html to cache', name, value);
836
+ cache[name] = value;
837
+ $module
838
+ .data(metadata.cache, cache)
839
+ ;
840
+ }
841
+ }
842
+ },
843
+
844
+ addResults: function(html) {
845
+ if( $.isFunction(settings.onResultsAdd) ) {
846
+ if( settings.onResultsAdd.call($results, html) === false ) {
847
+ module.debug('onResultsAdd callback cancelled default action');
848
+ return false;
849
+ }
850
+ }
851
+ if(html) {
852
+ $results
853
+ .html(html)
854
+ ;
855
+ module.refreshResults();
856
+ if(settings.selectFirstResult) {
857
+ module.select.firstResult();
858
+ }
859
+ module.showResults();
860
+ }
861
+ else {
862
+ module.hideResults(function() {
863
+ $results.empty();
864
+ });
865
+ }
866
+ },
867
+
868
+ showResults: function(callback) {
869
+ callback = $.isFunction(callback)
870
+ ? callback
871
+ : function(){}
872
+ ;
873
+ if(resultsDismissed) {
874
+ return;
875
+ }
876
+ if(!module.is.visible() && module.has.results()) {
877
+ if( module.can.transition() ) {
878
+ module.debug('Showing results with css animations');
879
+ $results
880
+ .transition({
881
+ animation : settings.transition + ' in',
882
+ debug : settings.debug,
883
+ verbose : settings.verbose,
884
+ duration : settings.duration,
885
+ onComplete : function() {
886
+ callback();
887
+ },
888
+ queue : true
889
+ })
890
+ ;
891
+ }
892
+ else {
893
+ module.debug('Showing results with javascript');
894
+ $results
895
+ .stop()
896
+ .fadeIn(settings.duration, settings.easing)
897
+ ;
898
+ }
899
+ settings.onResultsOpen.call($results);
900
+ }
901
+ },
902
+ hideResults: function(callback) {
903
+ callback = $.isFunction(callback)
904
+ ? callback
905
+ : function(){}
906
+ ;
907
+ if( module.is.visible() ) {
908
+ if( module.can.transition() ) {
909
+ module.debug('Hiding results with css animations');
910
+ $results
911
+ .transition({
912
+ animation : settings.transition + ' out',
913
+ debug : settings.debug,
914
+ verbose : settings.verbose,
915
+ duration : settings.duration,
916
+ onComplete : function() {
917
+ callback();
918
+ },
919
+ queue : true
920
+ })
921
+ ;
922
+ }
923
+ else {
924
+ module.debug('Hiding results with javascript');
925
+ $results
926
+ .stop()
927
+ .fadeOut(settings.duration, settings.easing)
928
+ ;
929
+ }
930
+ settings.onResultsClose.call($results);
931
+ }
932
+ },
933
+
934
+ generateResults: function(response) {
935
+ module.debug('Generating html from response', response);
936
+ var
937
+ template = settings.templates[settings.type],
938
+ isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])),
939
+ isProperArray = ($.isArray(response[fields.results]) && response[fields.results].length > 0),
940
+ html = ''
941
+ ;
942
+ if(isProperObject || isProperArray ) {
943
+ if(settings.maxResults > 0) {
944
+ if(isProperObject) {
945
+ if(settings.type == 'standard') {
946
+ module.error(error.maxResults);
947
+ }
948
+ }
949
+ else {
950
+ response[fields.results] = response[fields.results].slice(0, settings.maxResults);
951
+ }
952
+ }
953
+ if($.isFunction(template)) {
954
+ html = template(response, fields);
955
+ }
956
+ else {
957
+ module.error(error.noTemplate, false);
958
+ }
959
+ }
960
+ else if(settings.showNoResults) {
961
+ html = module.displayMessage(error.noResults, 'empty');
962
+ }
963
+ settings.onResults.call(element, response);
964
+ return html;
965
+ },
966
+
967
+ displayMessage: function(text, type) {
968
+ type = type || 'standard';
969
+ module.debug('Displaying message', text, type);
970
+ module.addResults( settings.templates.message(text, type) );
971
+ return settings.templates.message(text, type);
972
+ },
973
+
974
+ setting: function(name, value) {
975
+ if( $.isPlainObject(name) ) {
976
+ $.extend(true, settings, name);
977
+ }
978
+ else if(value !== undefined) {
979
+ settings[name] = value;
980
+ }
981
+ else {
982
+ return settings[name];
983
+ }
984
+ },
985
+ internal: function(name, value) {
986
+ if( $.isPlainObject(name) ) {
987
+ $.extend(true, module, name);
988
+ }
989
+ else if(value !== undefined) {
990
+ module[name] = value;
991
+ }
992
+ else {
993
+ return module[name];
994
+ }
995
+ },
996
+ debug: function() {
997
+ if(!settings.silent && settings.debug) {
998
+ if(settings.performance) {
999
+ module.performance.log(arguments);
1000
+ }
1001
+ else {
1002
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1003
+ module.debug.apply(console, arguments);
1004
+ }
1005
+ }
1006
+ },
1007
+ verbose: function() {
1008
+ if(!settings.silent && settings.verbose && settings.debug) {
1009
+ if(settings.performance) {
1010
+ module.performance.log(arguments);
1011
+ }
1012
+ else {
1013
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1014
+ module.verbose.apply(console, arguments);
1015
+ }
1016
+ }
1017
+ },
1018
+ error: function() {
1019
+ if(!settings.silent) {
1020
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1021
+ module.error.apply(console, arguments);
1022
+ }
1023
+ },
1024
+ performance: {
1025
+ log: function(message) {
1026
+ var
1027
+ currentTime,
1028
+ executionTime,
1029
+ previousTime
1030
+ ;
1031
+ if(settings.performance) {
1032
+ currentTime = new Date().getTime();
1033
+ previousTime = time || currentTime;
1034
+ executionTime = currentTime - previousTime;
1035
+ time = currentTime;
1036
+ performance.push({
1037
+ 'Name' : message[0],
1038
+ 'Arguments' : [].slice.call(message, 1) || '',
1039
+ 'Element' : element,
1040
+ 'Execution Time' : executionTime
1041
+ });
1042
+ }
1043
+ clearTimeout(module.performance.timer);
1044
+ module.performance.timer = setTimeout(module.performance.display, 500);
1045
+ },
1046
+ display: function() {
1047
+ var
1048
+ title = settings.name + ':',
1049
+ totalTime = 0
1050
+ ;
1051
+ time = false;
1052
+ clearTimeout(module.performance.timer);
1053
+ $.each(performance, function(index, data) {
1054
+ totalTime += data['Execution Time'];
1055
+ });
1056
+ title += ' ' + totalTime + 'ms';
1057
+ if(moduleSelector) {
1058
+ title += ' \'' + moduleSelector + '\'';
1059
+ }
1060
+ if($allModules.length > 1) {
1061
+ title += ' ' + '(' + $allModules.length + ')';
1062
+ }
1063
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1064
+ console.groupCollapsed(title);
1065
+ if(console.table) {
1066
+ console.table(performance);
1067
+ }
1068
+ else {
1069
+ $.each(performance, function(index, data) {
1070
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
1071
+ });
1072
+ }
1073
+ console.groupEnd();
1074
+ }
1075
+ performance = [];
1076
+ }
1077
+ },
1078
+ invoke: function(query, passedArguments, context) {
1079
+ var
1080
+ object = instance,
1081
+ maxDepth,
1082
+ found,
1083
+ response
1084
+ ;
1085
+ passedArguments = passedArguments || queryArguments;
1086
+ context = element || context;
1087
+ if(typeof query == 'string' && object !== undefined) {
1088
+ query = query.split(/[\. ]/);
1089
+ maxDepth = query.length - 1;
1090
+ $.each(query, function(depth, value) {
1091
+ var camelCaseValue = (depth != maxDepth)
1092
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1093
+ : query
1094
+ ;
1095
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
1096
+ object = object[camelCaseValue];
1097
+ }
1098
+ else if( object[camelCaseValue] !== undefined ) {
1099
+ found = object[camelCaseValue];
1100
+ return false;
1101
+ }
1102
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
1103
+ object = object[value];
1104
+ }
1105
+ else if( object[value] !== undefined ) {
1106
+ found = object[value];
1107
+ return false;
1108
+ }
1109
+ else {
1110
+ return false;
1111
+ }
1112
+ });
1113
+ }
1114
+ if( $.isFunction( found ) ) {
1115
+ response = found.apply(context, passedArguments);
1116
+ }
1117
+ else if(found !== undefined) {
1118
+ response = found;
1119
+ }
1120
+ if($.isArray(returnedValue)) {
1121
+ returnedValue.push(response);
1122
+ }
1123
+ else if(returnedValue !== undefined) {
1124
+ returnedValue = [returnedValue, response];
1125
+ }
1126
+ else if(response !== undefined) {
1127
+ returnedValue = response;
1128
+ }
1129
+ return found;
1130
+ }
1131
+ };
1132
+ if(methodInvoked) {
1133
+ if(instance === undefined) {
1134
+ module.initialize();
1135
+ }
1136
+ module.invoke(query);
1137
+ }
1138
+ else {
1139
+ if(instance !== undefined) {
1140
+ instance.invoke('destroy');
1141
+ }
1142
+ module.initialize();
1143
+ }
1144
+
1145
+ })
1146
+ ;
1147
+
1148
+ return (returnedValue !== undefined)
1149
+ ? returnedValue
1150
+ : this
1151
+ ;
1152
+ };
1153
+
1154
+ $.fn.search.settings = {
1155
+
1156
+ name : 'Search',
1157
+ namespace : 'search',
1158
+
1159
+ silent : false,
1160
+ debug : false,
1161
+ verbose : false,
1162
+ performance : true,
1163
+
1164
+ // template to use (specified in settings.templates)
1165
+ type : 'standard',
1166
+
1167
+ // minimum characters required to search
1168
+ minCharacters : 1,
1169
+
1170
+ // whether to select first result after searching automatically
1171
+ selectFirstResult : false,
1172
+
1173
+ // API config
1174
+ apiSettings : false,
1175
+
1176
+ // object to search
1177
+ source : false,
1178
+
1179
+ // Whether search should query current term on focus
1180
+ searchOnFocus : true,
1181
+
1182
+ // fields to search
1183
+ searchFields : [
1184
+ 'title',
1185
+ 'description'
1186
+ ],
1187
+
1188
+ // field to display in standard results template
1189
+ displayField : '',
1190
+
1191
+ // whether to include fuzzy results in local search
1192
+ searchFullText : true,
1193
+
1194
+ // whether to add events to prompt automatically
1195
+ automatic : true,
1196
+
1197
+ // delay before hiding menu after blur
1198
+ hideDelay : 0,
1199
+
1200
+ // delay before searching
1201
+ searchDelay : 200,
1202
+
1203
+ // maximum results returned from local
1204
+ maxResults : 7,
1205
+
1206
+ // whether to store lookups in local cache
1207
+ cache : true,
1208
+
1209
+ // whether no results errors should be shown
1210
+ showNoResults : true,
1211
+
1212
+ // transition settings
1213
+ transition : 'scale',
1214
+ duration : 200,
1215
+ easing : 'easeOutExpo',
1216
+
1217
+ // callbacks
1218
+ onSelect : false,
1219
+ onResultsAdd : false,
1220
+
1221
+ onSearchQuery : function(query){},
1222
+ onResults : function(response){},
1223
+
1224
+ onResultsOpen : function(){},
1225
+ onResultsClose : function(){},
1226
+
1227
+ className: {
1228
+ animating : 'animating',
1229
+ active : 'active',
1230
+ empty : 'empty',
1231
+ focus : 'focus',
1232
+ hidden : 'hidden',
1233
+ loading : 'loading',
1234
+ results : 'results',
1235
+ pressed : 'down'
1236
+ },
1237
+
1238
+ error : {
1239
+ source : 'Cannot search. No source used, and Semantic API module was not included',
1240
+ noResults : 'Your search returned no results',
1241
+ logging : 'Error in debug logging, exiting.',
1242
+ noEndpoint : 'No search endpoint was specified',
1243
+ noTemplate : 'A valid template name was not specified.',
1244
+ serverError : 'There was an issue querying the server.',
1245
+ maxResults : 'Results must be an array to use maxResults setting',
1246
+ method : 'The method you called is not defined.'
1247
+ },
1248
+
1249
+ metadata: {
1250
+ cache : 'cache',
1251
+ results : 'results',
1252
+ result : 'result'
1253
+ },
1254
+
1255
+ regExp: {
1256
+ escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
1257
+ beginsWith : '(?:\s|^)'
1258
+ },
1259
+
1260
+ // maps api response attributes to internal representation
1261
+ fields: {
1262
+ categories : 'results', // array of categories (category view)
1263
+ categoryName : 'name', // name of category (category view)
1264
+ categoryResults : 'results', // array of results (category view)
1265
+ description : 'description', // result description
1266
+ image : 'image', // result image
1267
+ price : 'price', // result price
1268
+ results : 'results', // array of results (standard)
1269
+ title : 'title', // result title
1270
+ url : 'url', // result url
1271
+ action : 'action', // "view more" object name
1272
+ actionText : 'text', // "view more" text
1273
+ actionURL : 'url' // "view more" url
1274
+ },
1275
+
1276
+ selector : {
1277
+ prompt : '.prompt',
1278
+ searchButton : '.search.button',
1279
+ results : '.results',
1280
+ message : '.results > .message',
1281
+ category : '.category',
1282
+ result : '.result',
1283
+ title : '.title, .name'
1284
+ },
1285
+
1286
+ templates: {
1287
+ escape: function(string) {
1288
+ var
1289
+ badChars = /[&<>"'`]/g,
1290
+ shouldEscape = /[&<>"'`]/,
1291
+ escape = {
1292
+ "&": "&amp;",
1293
+ "<": "&lt;",
1294
+ ">": "&gt;",
1295
+ '"': "&quot;",
1296
+ "'": "&#x27;",
1297
+ "`": "&#x60;"
1298
+ },
1299
+ escapedChar = function(chr) {
1300
+ return escape[chr];
1301
+ }
1302
+ ;
1303
+ if(shouldEscape.test(string)) {
1304
+ return string.replace(badChars, escapedChar);
1305
+ }
1306
+ return string;
1307
+ },
1308
+ message: function(message, type) {
1309
+ var
1310
+ html = ''
1311
+ ;
1312
+ if(message !== undefined && type !== undefined) {
1313
+ html += ''
1314
+ + '<div class="message ' + type + '">'
1315
+ ;
1316
+ // message type
1317
+ if(type == 'empty') {
1318
+ html += ''
1319
+ + '<div class="header">No Results</div class="header">'
1320
+ + '<div class="description">' + message + '</div class="description">'
1321
+ ;
1322
+ }
1323
+ else {
1324
+ html += ' <div class="description">' + message + '</div>';
1325
+ }
1326
+ html += '</div>';
1327
+ }
1328
+ return html;
1329
+ },
1330
+ category: function(response, fields) {
1331
+ var
1332
+ html = '',
1333
+ escape = $.fn.search.settings.templates.escape
1334
+ ;
1335
+ if(response[fields.categoryResults] !== undefined) {
1336
+
1337
+ // each category
1338
+ $.each(response[fields.categoryResults], function(index, category) {
1339
+ if(category[fields.results] !== undefined && category.results.length > 0) {
1340
+
1341
+ html += '<div class="category">';
1342
+
1343
+ if(category[fields.categoryName] !== undefined) {
1344
+ html += '<div class="name">' + category[fields.categoryName] + '</div>';
1345
+ }
1346
+
1347
+ // each item inside category
1348
+ $.each(category.results, function(index, result) {
1349
+ if(result[fields.url]) {
1350
+ html += '<a class="result" href="' + result[fields.url] + '">';
1351
+ }
1352
+ else {
1353
+ html += '<a class="result">';
1354
+ }
1355
+ if(result[fields.image] !== undefined) {
1356
+ html += ''
1357
+ + '<div class="image">'
1358
+ + ' <img src="' + result[fields.image] + '">'
1359
+ + '</div>'
1360
+ ;
1361
+ }
1362
+ html += '<div class="content">';
1363
+ if(result[fields.price] !== undefined) {
1364
+ html += '<div class="price">' + result[fields.price] + '</div>';
1365
+ }
1366
+ if(result[fields.title] !== undefined) {
1367
+ html += '<div class="title">' + result[fields.title] + '</div>';
1368
+ }
1369
+ if(result[fields.description] !== undefined) {
1370
+ html += '<div class="description">' + result[fields.description] + '</div>';
1371
+ }
1372
+ html += ''
1373
+ + '</div>'
1374
+ ;
1375
+ html += '</a>';
1376
+ });
1377
+ html += ''
1378
+ + '</div>'
1379
+ ;
1380
+ }
1381
+ });
1382
+ if(response[fields.action]) {
1383
+ html += ''
1384
+ + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
1385
+ + response[fields.action][fields.actionText]
1386
+ + '</a>';
1387
+ }
1388
+ return html;
1389
+ }
1390
+ return false;
1391
+ },
1392
+ standard: function(response, fields) {
1393
+ var
1394
+ html = ''
1395
+ ;
1396
+ if(response[fields.results] !== undefined) {
1397
+
1398
+ // each result
1399
+ $.each(response[fields.results], function(index, result) {
1400
+ if(result[fields.url]) {
1401
+ html += '<a class="result" href="' + result[fields.url] + '">';
1402
+ }
1403
+ else {
1404
+ html += '<a class="result">';
1405
+ }
1406
+ if(result[fields.image] !== undefined) {
1407
+ html += ''
1408
+ + '<div class="image">'
1409
+ + ' <img src="' + result[fields.image] + '">'
1410
+ + '</div>'
1411
+ ;
1412
+ }
1413
+ html += '<div class="content">';
1414
+ if(result[fields.price] !== undefined) {
1415
+ html += '<div class="price">' + result[fields.price] + '</div>';
1416
+ }
1417
+ if(result[fields.title] !== undefined) {
1418
+ html += '<div class="title">' + result[fields.title] + '</div>';
1419
+ }
1420
+ if(result[fields.description] !== undefined) {
1421
+ html += '<div class="description">' + result[fields.description] + '</div>';
1422
+ }
1423
+ html += ''
1424
+ + '</div>'
1425
+ ;
1426
+ html += '</a>';
1427
+ });
1428
+
1429
+ if(response[fields.action]) {
1430
+ html += ''
1431
+ + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
1432
+ + response[fields.action][fields.actionText]
1433
+ + '</a>';
1434
+ }
1435
+ return html;
1436
+ }
1437
+ return false;
1438
+ }
1439
+ }
1440
+ };
1441
+
1442
+ })( jQuery, window, document );