porthos 3.0.0.beta

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 (388) hide show
  1. data/Gemfile +6 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +26 -0
  4. data/Rakefile +28 -0
  5. data/app/assets/images/Jcrop.gif +0 -0
  6. data/app/assets/images/button_grey_bg.png +0 -0
  7. data/app/assets/images/icons/avatar.png +0 -0
  8. data/app/assets/images/icons/filetypes/ai.png +0 -0
  9. data/app/assets/images/icons/filetypes/default.png +0 -0
  10. data/app/assets/images/icons/filetypes/doc.png +0 -0
  11. data/app/assets/images/icons/filetypes/eps.png +0 -0
  12. data/app/assets/images/icons/filetypes/mp3.png +0 -0
  13. data/app/assets/images/icons/filetypes/pdf.png +0 -0
  14. data/app/assets/images/icons/filetypes/psd.png +0 -0
  15. data/app/assets/images/icons/filetypes/swf.png +0 -0
  16. data/app/assets/images/icons/filetypes/wav.png +0 -0
  17. data/app/assets/images/icons/filetypes/zip.png +0 -0
  18. data/app/assets/images/layout2_bg_shadow.png +0 -0
  19. data/app/assets/images/layout3_bg_shadow.png +0 -0
  20. data/app/assets/images/ui_new.png +0 -0
  21. data/app/assets/images/wymeditor/icons.png +0 -0
  22. data/app/assets/javascripts/admin.js +7 -0
  23. data/app/assets/javascripts/admin/assets.js +147 -0
  24. data/app/assets/javascripts/admin/editor.js +2 -0
  25. data/app/assets/javascripts/admin/helpers.js +169 -0
  26. data/app/assets/javascripts/admin/items.js +267 -0
  27. data/app/assets/javascripts/admin/nodes.js +73 -0
  28. data/app/assets/javascripts/admin/settings.js +1 -0
  29. data/app/assets/javascripts/admin_extension.js +0 -0
  30. data/app/assets/javascripts/lib/ckeditor/LICENSE.html +1334 -0
  31. data/app/assets/javascripts/lib/ckeditor/adapters/jquery.js +6 -0
  32. data/app/assets/javascripts/lib/ckeditor/ckeditor.js +141 -0
  33. data/app/assets/javascripts/lib/ckeditor/ckeditor_basic.js +8 -0
  34. data/app/assets/javascripts/lib/ckeditor/ckeditor_basic_source.js +20 -0
  35. data/app/assets/javascripts/lib/ckeditor/config.js +26 -0
  36. data/app/assets/javascripts/lib/ckeditor/contents.css +50 -0
  37. data/app/assets/javascripts/lib/ckeditor/images/spacer.gif +0 -0
  38. data/app/assets/javascripts/lib/ckeditor/lang/_languages.js +6 -0
  39. data/app/assets/javascripts/lib/ckeditor/lang/_translationstatus.txt +60 -0
  40. data/app/assets/javascripts/lib/ckeditor/lang/en.js +6 -0
  41. data/app/assets/javascripts/lib/ckeditor/lang/sv.js +6 -0
  42. data/app/assets/javascripts/lib/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js +7 -0
  43. data/app/assets/javascripts/lib/ckeditor/plugins/a11yhelp/lang/en.js +6 -0
  44. data/app/assets/javascripts/lib/ckeditor/plugins/a11yhelp/lang/he.js +6 -0
  45. data/app/assets/javascripts/lib/ckeditor/plugins/about/dialogs/about.js +6 -0
  46. data/app/assets/javascripts/lib/ckeditor/plugins/about/dialogs/logo_ckeditor.png +0 -0
  47. data/app/assets/javascripts/lib/ckeditor/plugins/adobeair/plugin.js +6 -0
  48. data/app/assets/javascripts/lib/ckeditor/plugins/autogrow/plugin.js +6 -0
  49. data/app/assets/javascripts/lib/ckeditor/plugins/clipboard/dialogs/paste.js +7 -0
  50. data/app/assets/javascripts/lib/ckeditor/plugins/colordialog/dialogs/colordialog.js +7 -0
  51. data/app/assets/javascripts/lib/ckeditor/plugins/dialog/dialogDefinition.js +4 -0
  52. data/app/assets/javascripts/lib/ckeditor/plugins/div/dialogs/div.js +8 -0
  53. data/app/assets/javascripts/lib/ckeditor/plugins/find/dialogs/find.js +9 -0
  54. data/app/assets/javascripts/lib/ckeditor/plugins/flash/dialogs/flash.js +9 -0
  55. data/app/assets/javascripts/lib/ckeditor/plugins/flash/images/placeholder.png +0 -0
  56. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/button.js +6 -0
  57. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/checkbox.js +6 -0
  58. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/form.js +6 -0
  59. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/hiddenfield.js +6 -0
  60. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/radio.js +6 -0
  61. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/select.js +9 -0
  62. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/textarea.js +6 -0
  63. data/app/assets/javascripts/lib/ckeditor/plugins/forms/dialogs/textfield.js +6 -0
  64. data/app/assets/javascripts/lib/ckeditor/plugins/forms/images/hiddenfield.gif +0 -0
  65. data/app/assets/javascripts/lib/ckeditor/plugins/iframe/dialogs/iframe.js +7 -0
  66. data/app/assets/javascripts/lib/ckeditor/plugins/iframe/images/placeholder.png +0 -0
  67. data/app/assets/javascripts/lib/ckeditor/plugins/iframedialog/plugin.js +6 -0
  68. data/app/assets/javascripts/lib/ckeditor/plugins/image/dialogs/image.js +13 -0
  69. data/app/assets/javascripts/lib/ckeditor/plugins/link/dialogs/anchor.js +6 -0
  70. data/app/assets/javascripts/lib/ckeditor/plugins/link/dialogs/link.js +11 -0
  71. data/app/assets/javascripts/lib/ckeditor/plugins/link/images/anchor.gif +0 -0
  72. data/app/assets/javascripts/lib/ckeditor/plugins/liststyle/dialogs/liststyle.js +6 -0
  73. data/app/assets/javascripts/lib/ckeditor/plugins/pagebreak/images/pagebreak.gif +0 -0
  74. data/app/assets/javascripts/lib/ckeditor/plugins/pastefromword/filter/default.js +10 -0
  75. data/app/assets/javascripts/lib/ckeditor/plugins/pastetext/dialogs/pastetext.js +6 -0
  76. data/app/assets/javascripts/lib/ckeditor/plugins/placeholder/dialogs/placeholder.js +6 -0
  77. data/app/assets/javascripts/lib/ckeditor/plugins/placeholder/lang/en.js +6 -0
  78. data/app/assets/javascripts/lib/ckeditor/plugins/placeholder/placeholder.gif +0 -0
  79. data/app/assets/javascripts/lib/ckeditor/plugins/placeholder/plugin.js +6 -0
  80. data/app/assets/javascripts/lib/ckeditor/plugins/scayt/dialogs/options.js +8 -0
  81. data/app/assets/javascripts/lib/ckeditor/plugins/scayt/dialogs/toolbar.css +6 -0
  82. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_address.png +0 -0
  83. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_blockquote.png +0 -0
  84. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_div.png +0 -0
  85. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h1.png +0 -0
  86. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h2.png +0 -0
  87. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h3.png +0 -0
  88. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h4.png +0 -0
  89. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h5.png +0 -0
  90. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_h6.png +0 -0
  91. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_p.png +0 -0
  92. data/app/assets/javascripts/lib/ckeditor/plugins/showblocks/images/block_pre.png +0 -0
  93. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/dialogs/smiley.js +7 -0
  94. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/angel_smile.gif +0 -0
  95. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/angry_smile.gif +0 -0
  96. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/broken_heart.gif +0 -0
  97. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/confused_smile.gif +0 -0
  98. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/cry_smile.gif +0 -0
  99. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/devil_smile.gif +0 -0
  100. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/embaressed_smile.gif +0 -0
  101. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/envelope.gif +0 -0
  102. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/heart.gif +0 -0
  103. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/kiss.gif +0 -0
  104. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/lightbulb.gif +0 -0
  105. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/omg_smile.gif +0 -0
  106. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/regular_smile.gif +0 -0
  107. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/sad_smile.gif +0 -0
  108. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/shades_smile.gif +0 -0
  109. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/teeth_smile.gif +0 -0
  110. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/thumbs_down.gif +0 -0
  111. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/thumbs_up.gif +0 -0
  112. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/tounge_smile.gif +0 -0
  113. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/whatchutalkingabout_smile.gif +0 -0
  114. data/app/assets/javascripts/lib/ckeditor/plugins/smiley/images/wink_smile.gif +0 -0
  115. data/app/assets/javascripts/lib/ckeditor/plugins/specialchar/dialogs/specialchar.js +7 -0
  116. data/app/assets/javascripts/lib/ckeditor/plugins/specialchar/lang/en.js +6 -0
  117. data/app/assets/javascripts/lib/ckeditor/plugins/styles/styles/default.js +6 -0
  118. data/app/assets/javascripts/lib/ckeditor/plugins/table/dialogs/table.js +9 -0
  119. data/app/assets/javascripts/lib/ckeditor/plugins/tableresize/plugin.js +7 -0
  120. data/app/assets/javascripts/lib/ckeditor/plugins/tabletools/dialogs/tableCell.js +8 -0
  121. data/app/assets/javascripts/lib/ckeditor/plugins/templates/dialogs/templates.js +7 -0
  122. data/app/assets/javascripts/lib/ckeditor/plugins/templates/templates/default.js +6 -0
  123. data/app/assets/javascripts/lib/ckeditor/plugins/templates/templates/images/template1.gif +0 -0
  124. data/app/assets/javascripts/lib/ckeditor/plugins/templates/templates/images/template2.gif +0 -0
  125. data/app/assets/javascripts/lib/ckeditor/plugins/templates/templates/images/template3.gif +0 -0
  126. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/dialogs/uicolor.js +7 -0
  127. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/lang/en.js +6 -0
  128. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/lang/he.js +6 -0
  129. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/plugin.js +6 -0
  130. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/uicolor.gif +0 -0
  131. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/assets/hue_bg.png +0 -0
  132. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/assets/hue_thumb.png +0 -0
  133. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/assets/picker_mask.png +0 -0
  134. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/assets/picker_thumb.png +0 -0
  135. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/assets/yui.css +6 -0
  136. data/app/assets/javascripts/lib/ckeditor/plugins/uicolor/yui/yui.js +76 -0
  137. data/app/assets/javascripts/lib/ckeditor/plugins/wsc/dialogs/ciframe.html +49 -0
  138. data/app/assets/javascripts/lib/ckeditor/plugins/wsc/dialogs/tmpFrameset.html +52 -0
  139. data/app/assets/javascripts/lib/ckeditor/plugins/wsc/dialogs/wsc.css +6 -0
  140. data/app/assets/javascripts/lib/ckeditor/plugins/wsc/dialogs/wsc.js +7 -0
  141. data/app/assets/javascripts/lib/ckeditor/skins/kama/dialog.css +515 -0
  142. data/app/assets/javascripts/lib/ckeditor/skins/kama/editor.css +1115 -0
  143. data/app/assets/javascripts/lib/ckeditor/skins/kama/icons.png +0 -0
  144. data/app/assets/javascripts/lib/ckeditor/skins/kama/icons_rtl.png +0 -0
  145. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/dialog_sides.gif +0 -0
  146. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/dialog_sides.png +0 -0
  147. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/dialog_sides_rtl.png +0 -0
  148. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/mini.gif +0 -0
  149. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/noimage.png +0 -0
  150. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/sprites.png +0 -0
  151. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/sprites_ie6.png +0 -0
  152. data/app/assets/javascripts/lib/ckeditor/skins/kama/images/toolbar_start.gif +0 -0
  153. data/app/assets/javascripts/lib/ckeditor/skins/kama/skin.js +7 -0
  154. data/app/assets/javascripts/lib/ckeditor/skins/kama/templates.css +65 -0
  155. data/app/assets/javascripts/lib/ckeditor/themes/default/theme.js +8 -0
  156. data/app/assets/javascripts/lib/jquery-1.6.1.min.js +18 -0
  157. data/app/assets/javascripts/lib/jquery-ui-1.8.13.min.js +407 -0
  158. data/app/assets/javascripts/lib/jquery.jcrop.min.js +246 -0
  159. data/app/assets/javascripts/lib/jquery.smart_autocomplete.js +519 -0
  160. data/app/assets/javascripts/lib/underscore.min.js +26 -0
  161. data/app/assets/javascripts/lib/underscore.string.min.js +8 -0
  162. data/app/assets/javascripts/rails.js +148 -0
  163. data/app/assets/stylesheets/admin.css +9 -0
  164. data/app/assets/stylesheets/admin_extensions.css.scss +0 -0
  165. data/app/assets/stylesheets/clearing.css +28 -0
  166. data/app/assets/stylesheets/elements.css.erb +335 -0
  167. data/app/assets/stylesheets/forms.css.scss +118 -0
  168. data/app/assets/stylesheets/jquery.jcrop.css +28 -0
  169. data/app/assets/stylesheets/layout.css.erb +269 -0
  170. data/app/assets/stylesheets/views/assets.css.erb +112 -0
  171. data/app/assets/stylesheets/views/nodes.css +47 -0
  172. data/app/assets/stylesheets/views/pages.css.scss +136 -0
  173. data/app/assets/stylesheets/views/sessions.css +22 -0
  174. data/app/assets/stylesheets/views/tags.css +15 -0
  175. data/app/assets/stylesheets/views/users.css +16 -0
  176. data/app/controllers/admin/assets_controller.rb +132 -0
  177. data/app/controllers/admin/content_templates_controller.rb +56 -0
  178. data/app/controllers/admin/data_controller.rb +93 -0
  179. data/app/controllers/admin/datum_templates_controller.rb +59 -0
  180. data/app/controllers/admin/items_controller.rb +114 -0
  181. data/app/controllers/admin/link_lists_controller.rb +41 -0
  182. data/app/controllers/admin/links_controller.rb +65 -0
  183. data/app/controllers/admin/nodes_controller.rb +114 -0
  184. data/app/controllers/admin/page_templates_controller.rb +56 -0
  185. data/app/controllers/admin/redirects_controller.rb +58 -0
  186. data/app/controllers/admin/sessions_controller.rb +27 -0
  187. data/app/controllers/admin/site_settings_controller.rb +58 -0
  188. data/app/controllers/admin/tags_controller.rb +71 -0
  189. data/app/controllers/admin/users_controller.rb +55 -0
  190. data/app/controllers/application_controller.rb +8 -0
  191. data/app/controllers/pages_controller.rb +115 -0
  192. data/app/helpers/data_helper.rb +11 -0
  193. data/app/helpers/link_lists_helper.rb +16 -0
  194. data/app/models/asset.rb +189 -0
  195. data/app/models/custom_page.rb +33 -0
  196. data/app/models/data/asset_association.rb +73 -0
  197. data/app/models/data/datum_collection.rb +46 -0
  198. data/app/models/data/field.rb +26 -0
  199. data/app/models/data/field_set.rb +37 -0
  200. data/app/models/data/link_field.rb +7 -0
  201. data/app/models/data/page_association.rb +26 -0
  202. data/app/models/data/string_field.rb +13 -0
  203. data/app/models/datum.rb +22 -0
  204. data/app/models/datum_template.rb +143 -0
  205. data/app/models/datum_templates/asset_association_template.rb +3 -0
  206. data/app/models/datum_templates/association_field_template.rb +2 -0
  207. data/app/models/datum_templates/datum_collection_template.rb +15 -0
  208. data/app/models/datum_templates/field_set_template.rb +5 -0
  209. data/app/models/datum_templates/field_template.rb +6 -0
  210. data/app/models/datum_templates/link_field_template.rb +2 -0
  211. data/app/models/datum_templates/page_association_template.rb +4 -0
  212. data/app/models/datum_templates/string_field_template.rb +4 -0
  213. data/app/models/file_template.rb +105 -0
  214. data/app/models/file_templates/field_set_file_template.rb +7 -0
  215. data/app/models/file_templates/page_file_template.rb +14 -0
  216. data/app/models/image_asset.rb +102 -0
  217. data/app/models/item.rb +115 -0
  218. data/app/models/link.rb +46 -0
  219. data/app/models/link_list.rb +30 -0
  220. data/app/models/node.rb +106 -0
  221. data/app/models/observers/node_observer.rb +9 -0
  222. data/app/models/page.rb +167 -0
  223. data/app/models/redirect.rb +16 -0
  224. data/app/models/section.rb +30 -0
  225. data/app/models/setting.rb +4 -0
  226. data/app/models/site_setting.rb +11 -0
  227. data/app/models/template.rb +25 -0
  228. data/app/models/templates/content_template.rb +101 -0
  229. data/app/models/templates/page_template.rb +59 -0
  230. data/app/models/user.rb +67 -0
  231. data/app/views/admin/assets/_create_callback_form.html.erb +11 -0
  232. data/app/views/admin/assets/_sub_nav.html.erb +45 -0
  233. data/app/views/admin/assets/create.html.erb +10 -0
  234. data/app/views/admin/assets/edit.html.erb +91 -0
  235. data/app/views/admin/assets/edit_cropping.html.erb +44 -0
  236. data/app/views/admin/assets/incomplete.html.erb +39 -0
  237. data/app/views/admin/assets/index.html.erb +76 -0
  238. data/app/views/admin/assets/new.html.erb +20 -0
  239. data/app/views/admin/assets/search.html.erb +60 -0
  240. data/app/views/admin/assets/show.html.erb +45 -0
  241. data/app/views/admin/content_templates/_form.html.erb +18 -0
  242. data/app/views/admin/content_templates/edit.html.erb +14 -0
  243. data/app/views/admin/content_templates/index.html.erb +36 -0
  244. data/app/views/admin/content_templates/new.html.erb +14 -0
  245. data/app/views/admin/content_templates/show.html.erb +57 -0
  246. data/app/views/admin/data/_asset_association.html.erb +59 -0
  247. data/app/views/admin/data/_asset_association_form.html.erb +21 -0
  248. data/app/views/admin/data/_field.html.erb +7 -0
  249. data/app/views/admin/data/_field_form.html.erb +27 -0
  250. data/app/views/admin/data/_field_set.html.erb +7 -0
  251. data/app/views/admin/data/_field_set_form.html.erb +14 -0
  252. data/app/views/admin/data/_form.html.erb +14 -0
  253. data/app/views/admin/data/_link_field.html.erb +9 -0
  254. data/app/views/admin/data/_link_field_form.html.erb +22 -0
  255. data/app/views/admin/data/_page_association.html.erb +3 -0
  256. data/app/views/admin/data/_page_association_form.html.erb +8 -0
  257. data/app/views/admin/data/edit.html.erb +20 -0
  258. data/app/views/admin/data/index.html.erb +61 -0
  259. data/app/views/admin/data/new.html.erb +20 -0
  260. data/app/views/admin/datum_templates/_asset_association_template_form.html.erb +2 -0
  261. data/app/views/admin/datum_templates/_datum_collection_template_form.html.erb +23 -0
  262. data/app/views/admin/datum_templates/_field_set_template_form.html.erb +7 -0
  263. data/app/views/admin/datum_templates/_field_template_form.html.erb +1 -0
  264. data/app/views/admin/datum_templates/_form.html.erb +25 -0
  265. data/app/views/admin/datum_templates/_page_association_template_form.html.erb +2 -0
  266. data/app/views/admin/datum_templates/_string_field_template_form.html.erb +12 -0
  267. data/app/views/admin/datum_templates/edit.html.erb +14 -0
  268. data/app/views/admin/datum_templates/new.html.erb +14 -0
  269. data/app/views/admin/items/_asset_association.html.erb +6 -0
  270. data/app/views/admin/items/_details.html.erb +95 -0
  271. data/app/views/admin/items/_form.html.erb +20 -0
  272. data/app/views/admin/items/_page_form.html.erb +27 -0
  273. data/app/views/admin/items/_row.html.erb +47 -0
  274. data/app/views/admin/items/_sub_nav.html.erb +60 -0
  275. data/app/views/admin/items/index.html.erb +75 -0
  276. data/app/views/admin/items/new.html.erb +5 -0
  277. data/app/views/admin/items/page.html.erb +155 -0
  278. data/app/views/admin/items/search.html.erb +26 -0
  279. data/app/views/admin/items/section.html.erb +152 -0
  280. data/app/views/admin/link_lists/_form.html.erb +8 -0
  281. data/app/views/admin/link_lists/edit.html.erb +11 -0
  282. data/app/views/admin/link_lists/show.html.erb +45 -0
  283. data/app/views/admin/links/_form.html.erb +14 -0
  284. data/app/views/admin/links/edit.html.erb +11 -0
  285. data/app/views/admin/links/new.html.erb +11 -0
  286. data/app/views/admin/nodes/_form.html.erb +88 -0
  287. data/app/views/admin/nodes/_list_of_nodes.html.erb +11 -0
  288. data/app/views/admin/nodes/_node.html.erb +23 -0
  289. data/app/views/admin/nodes/_nodes_tree.html.erb +7 -0
  290. data/app/views/admin/nodes/_place_node.html.erb +11 -0
  291. data/app/views/admin/nodes/_sub_nav.html.erb +12 -0
  292. data/app/views/admin/nodes/edit.html.erb +10 -0
  293. data/app/views/admin/nodes/index.html.erb +26 -0
  294. data/app/views/admin/nodes/new.html.erb +10 -0
  295. data/app/views/admin/nodes/place.html.erb +37 -0
  296. data/app/views/admin/page_templates/_form.html.erb +51 -0
  297. data/app/views/admin/page_templates/edit.html.erb +14 -0
  298. data/app/views/admin/page_templates/index.html.erb +42 -0
  299. data/app/views/admin/page_templates/new.html.erb +14 -0
  300. data/app/views/admin/page_templates/pages.html.erb +28 -0
  301. data/app/views/admin/page_templates/show.html.erb +64 -0
  302. data/app/views/admin/redirects/edit.html.erb +25 -0
  303. data/app/views/admin/redirects/index.html.erb +38 -0
  304. data/app/views/admin/redirects/new.html.erb +25 -0
  305. data/app/views/admin/sessions/new.html.erb +17 -0
  306. data/app/views/admin/sessions/token.js.erb +1 -0
  307. data/app/views/admin/shared/_error_messages.html.erb +7 -0
  308. data/app/views/admin/shared/_settings_sub_nav.html.erb +8 -0
  309. data/app/views/admin/site_settings/_form.html.erb +5 -0
  310. data/app/views/admin/site_settings/edit.html.erb +20 -0
  311. data/app/views/admin/site_settings/index.html.erb +45 -0
  312. data/app/views/admin/site_settings/new.html.erb +20 -0
  313. data/app/views/admin/taggables/_asset.html.erb +10 -0
  314. data/app/views/admin/taggables/_page.html.erb +9 -0
  315. data/app/views/admin/taggables/_tag_collection.html.erb +2 -0
  316. data/app/views/admin/tags/edit.html.erb +18 -0
  317. data/app/views/admin/tags/index.html.erb +34 -0
  318. data/app/views/admin/tags/new.html.erb +18 -0
  319. data/app/views/admin/tags/search.js.erb +5 -0
  320. data/app/views/admin/tags/show.html.erb +29 -0
  321. data/app/views/admin/users/_form.html.erb +22 -0
  322. data/app/views/admin/users/_sub_nav.html.erb +12 -0
  323. data/app/views/admin/users/_user.html.erb +23 -0
  324. data/app/views/admin/users/edit.html.erb +18 -0
  325. data/app/views/admin/users/index.html.erb +22 -0
  326. data/app/views/admin/users/new.html.erb +15 -0
  327. data/app/views/admin/users/search.html.erb +19 -0
  328. data/app/views/field_set_templates/default/_show.html.erb +6 -0
  329. data/app/views/layouts/admin/_account_nav.html.erb +7 -0
  330. data/app/views/layouts/admin/_main_nav.html.erb +8 -0
  331. data/app/views/layouts/admin/application.html.erb +26 -0
  332. data/app/views/layouts/admin/sessions.html.erb +18 -0
  333. data/app/views/pages/_preview.html.erb +13 -0
  334. data/app/views/pages/contents/content_images/_collection.html.erb +26 -0
  335. data/app/views/pages/contents/content_images/_content_image.html.erb +19 -0
  336. data/app/views/pages/contents/content_teasers/_collection.html.erb +8 -0
  337. data/app/views/pages/contents/content_teasers/_content_teaser.html.erb +32 -0
  338. data/app/views/pages/contents/content_textfields/_content_textfield.html.erb +1 -0
  339. data/app/views/pages/contents/content_videos/_content_video.html.erb +1 -0
  340. data/app/views/pages/contents/modules/date_archive/_content.html.erb +23 -0
  341. data/app/views/pages/contents/modules/sub_navigation/_content.html.erb +5 -0
  342. data/app/views/pages/templates/default/_admin_in_list.html.erb +4 -0
  343. data/app/views/pages/templates/default/categories.html.erb +13 -0
  344. data/app/views/pages/templates/default/category.html.erb +13 -0
  345. data/app/views/pages/templates/default/default_renderer.rb +115 -0
  346. data/app/views/pages/templates/default/index.html.erb +13 -0
  347. data/app/views/pages/templates/default/index.rss.builder +19 -0
  348. data/app/views/pages/templates/default/search.html.erb +24 -0
  349. data/app/views/pages/templates/default/show.html.erb +6 -0
  350. data/app/views/shared/404.html.erb +1 -0
  351. data/config/initializers/locale.rb +1 -0
  352. data/config/initializers/mime_types.rb +13 -0
  353. data/config/initializers/overrides.rb +34 -0
  354. data/config/initializers/tanker.rb +1 -0
  355. data/config/locales/sv-SE.yml +543 -0
  356. data/config/routes.rb +97 -0
  357. data/lib/generators/porthos/USAGE +3 -0
  358. data/lib/generators/porthos/porthos_generator.rb +35 -0
  359. data/lib/generators/porthos/templates/mongo.yml +15 -0
  360. data/lib/porthos.rb +53 -0
  361. data/lib/porthos/active_record/restrictions.rb +36 -0
  362. data/lib/porthos/active_record/settingable.rb +49 -0
  363. data/lib/porthos/admin.rb +25 -0
  364. data/lib/porthos/authentication.rb +72 -0
  365. data/lib/porthos/config.rb +18 -0
  366. data/lib/porthos/datum_methods.rb +53 -0
  367. data/lib/porthos/engine.rb +56 -0
  368. data/lib/porthos/helpers/application_helper.rb +140 -0
  369. data/lib/porthos/mongo_mapper/acts_as_uri.rb +59 -0
  370. data/lib/porthos/mongo_mapper/callbacks.rb +13 -0
  371. data/lib/porthos/mongo_mapper/extensions.rb +58 -0
  372. data/lib/porthos/mongo_mapper/instructable.rb +36 -0
  373. data/lib/porthos/mongo_mapper/observer.rb +34 -0
  374. data/lib/porthos/mongo_mapper/taggable.rb +136 -0
  375. data/lib/porthos/page_renderer.rb +66 -0
  376. data/lib/porthos/public.rb +56 -0
  377. data/lib/porthos/redirects.rb +23 -0
  378. data/lib/porthos/routing.rb +256 -0
  379. data/lib/porthos/s3_storage.rb +61 -0
  380. data/lib/porthos/tags_autocomplete_app.rb +32 -0
  381. data/lib/porthos/tanking.rb +9 -0
  382. data/lib/porthos/test_helpers/assets_test_helper.rb +72 -0
  383. data/lib/porthos/test_helpers/pages_test_helper.rb +9 -0
  384. data/lib/porthos/url_resolver.rb +108 -0
  385. data/lib/porthos/validators.rb +14 -0
  386. data/lib/porthos/version.rb +3 -0
  387. data/lib/tasks/porthos_tasks.rake +217 -0
  388. metadata +774 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * jquery.Jcrop.min.js v0.9.9 (build:20110608)
3
+ * jQuery Image Cropping Plugin
4
+ * @author Kelly Hallman <khallman@gmail.com>
5
+ * Copyright (c) 2008-2011 Kelly Hallman - released under MIT License
6
+ * https://github.com/tapmodo/Jcrop
7
+ */
8
+
9
+ (function($){$.Jcrop=function(obj,opt){var options=$.extend({},$.Jcrop.defaults),docOffset,lastcurs,ie6mode=false;function px(n){return parseInt(n,10)+'px';}
10
+ function pct(n){return parseInt(n,10)+'%';}
11
+ function cssClass(cl){return options.baseClass+'-'+cl;}
12
+ function supportsColorFade(){return $.fx.step.hasOwnProperty('backgroundColor');}
13
+ function getPos(obj)
14
+ {var pos=$(obj).offset();return[pos.left,pos.top];}
15
+ function mouseAbs(e)
16
+ {return[(e.pageX-docOffset[0]),(e.pageY-docOffset[1])];}
17
+ function setOptions(opt)
18
+ {if(typeof(opt)!=='object'){opt={};}
19
+ options=$.extend(options,opt);if(typeof(options.onChange)!=='function'){options.onChange=function(){};}
20
+ if(typeof(options.onSelect)!=='function'){options.onSelect=function(){};}
21
+ if(typeof(options.onRelease)!=='function'){options.onRelease=function(){};}}
22
+ function myCursor(type)
23
+ {if(type!==lastcurs){Tracker.setCursor(type);lastcurs=type;}}
24
+ function startDragMode(mode,pos)
25
+ {docOffset=getPos($img);Tracker.setCursor(mode==='move'?mode:mode+'-resize');if(mode==='move'){return Tracker.activateHandlers(createMover(pos),doneSelect);}
26
+ var fc=Coords.getFixed();var opp=oppLockCorner(mode);var opc=Coords.getCorner(oppLockCorner(opp));Coords.setPressed(Coords.getCorner(opp));Coords.setCurrent(opc);Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);}
27
+ function dragmodeHandler(mode,f)
28
+ {return function(pos){if(!options.aspectRatio){switch(mode){case'e':pos[1]=f.y2;break;case'w':pos[1]=f.y2;break;case'n':pos[0]=f.x2;break;case's':pos[0]=f.x2;break;}}else{switch(mode){case'e':pos[1]=f.y+1;break;case'w':pos[1]=f.y+1;break;case'n':pos[0]=f.x+1;break;case's':pos[0]=f.x+1;break;}}
29
+ Coords.setCurrent(pos);Selection.update();};}
30
+ function createMover(pos)
31
+ {var lloc=pos;KeyManager.watchKeys();return function(pos){Coords.moveOffset([pos[0]-lloc[0],pos[1]-lloc[1]]);lloc=pos;Selection.update();};}
32
+ function oppLockCorner(ord)
33
+ {switch(ord){case'n':return'sw';case's':return'nw';case'e':return'nw';case'w':return'ne';case'ne':return'sw';case'nw':return'se';case'se':return'nw';case'sw':return'ne';}}
34
+ function createDragger(ord)
35
+ {return function(e){if(options.disabled){return false;}
36
+ if((ord==='move')&&!options.allowMove){return false;}
37
+ btndown=true;startDragMode(ord,mouseAbs(e));e.stopPropagation();e.preventDefault();return false;};}
38
+ function presize($obj,w,h)
39
+ {var nw=$obj.width(),nh=$obj.height();if((nw>w)&&w>0){nw=w;nh=(w/$obj.width())*$obj.height();}
40
+ if((nh>h)&&h>0){nh=h;nw=(h/$obj.height())*$obj.width();}
41
+ xscale=$obj.width()/nw;yscale=$obj.height()/nh;$obj.width(nw).height(nh);}
42
+ function unscale(c)
43
+ {return{x:parseInt(c.x*xscale,10),y:parseInt(c.y*yscale,10),x2:parseInt(c.x2*xscale,10),y2:parseInt(c.y2*yscale,10),w:parseInt(c.w*xscale,10),h:parseInt(c.h*yscale,10)};}
44
+ function doneSelect(pos)
45
+ {var c=Coords.getFixed();if((c.w>options.minSelect[0])&&(c.h>options.minSelect[1])){Selection.enableHandles();Selection.done();}else{Selection.release();}
46
+ Tracker.setCursor(options.allowSelect?'crosshair':'default');}
47
+ function newSelection(e)
48
+ {if(options.disabled){return false;}
49
+ if(!options.allowSelect){return false;}
50
+ btndown=true;docOffset=getPos($img);Selection.disableHandles();myCursor('crosshair');var pos=mouseAbs(e);Coords.setPressed(pos);Selection.update();Tracker.activateHandlers(selectDrag,doneSelect);KeyManager.watchKeys();e.stopPropagation();e.preventDefault();return false;}
51
+ function selectDrag(pos)
52
+ {Coords.setCurrent(pos);Selection.update();}
53
+ function newTracker()
54
+ {var trk=$('<div></div>').addClass(cssClass('tracker'));if($.browser.msie){trk.css({opacity:0,backgroundColor:'white'});}
55
+ return trk;}
56
+ if($.browser.msie&&($.browser.version.split('.')[0]==='6')){ie6mode=true;}
57
+ if(typeof(obj)!=='object'){obj=$(obj)[0];}
58
+ if(typeof(opt)!=='object'){opt={};}
59
+ setOptions(opt);var img_css={border:'none',margin:0,padding:0,position:'absolute'};var $origimg=$(obj);var $img=$origimg.clone().removeAttr('id').css(img_css);$img.width($origimg.width());$img.height($origimg.height());$origimg.after($img).hide();presize($img,options.boxWidth,options.boxHeight);var boundx=$img.width(),boundy=$img.height(),$div=$('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({position:'relative',backgroundColor:options.bgColor}).insertAfter($origimg).append($img);delete(options.bgColor);if(options.addClass){$div.addClass(options.addClass);}
60
+ var $img2=$('<img />').attr('src',$img.attr('src')).css(img_css).width(boundx).height(boundy),$img_holder=$('<div />').width(pct(100)).height(pct(100)).css({zIndex:310,position:'absolute',overflow:'hidden'}).append($img2),$hdl_holder=$('<div />').width(pct(100)).height(pct(100)).css('zIndex',320),$sel=$('<div />').css({position:'absolute',zIndex:300}).insertBefore($img).append($img_holder,$hdl_holder);if(ie6mode){$sel.css({overflowY:'hidden'});}
61
+ var bound=options.boundary;var $trk=newTracker().width(boundx+(bound*2)).height(boundy+(bound*2)).css({position:'absolute',top:px(-bound),left:px(-bound),zIndex:290}).mousedown(newSelection);var bgopacity=options.bgOpacity,xlimit,ylimit,xmin,ymin,xscale,yscale,enabled=true,btndown,animating,shift_down;docOffset=getPos($img);var Touch=(function(){function hasTouchSupport(){var support={},events=['touchstart','touchmove','touchend'],el=document.createElement('div'),i;try{for(i=0;i<events.length;i++){var eventName=events[i];eventName='on'+eventName;var isSupported=(eventName in el);if(!isSupported){el.setAttribute(eventName,'return;');isSupported=typeof el[eventName]=='function';}
62
+ support[events[i]]=isSupported;}
63
+ return support.touchstart&&support.touchend&&support.touchmove;}
64
+ catch(err){return false;}}
65
+ function detectSupport(){if((options.touchSupport===true)||(options.touchSupport===false))return options.touchSupport;else return hasTouchSupport();}
66
+ return{createDragger:function(ord){return function(e){e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;if(options.disabled){return false;}
67
+ if((ord==='move')&&!options.allowMove){return false;}
68
+ btndown=true;startDragMode(ord,mouseAbs(e));e.stopPropagation();e.preventDefault();return false;};},newSelection:function(e){e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return newSelection(e);},isSupported:hasTouchSupport,support:detectSupport()};}());var Coords=(function(){var x1=0,y1=0,x2=0,y2=0,ox,oy;function setPressed(pos)
69
+ {pos=rebound(pos);x2=x1=pos[0];y2=y1=pos[1];}
70
+ function setCurrent(pos)
71
+ {pos=rebound(pos);ox=pos[0]-x2;oy=pos[1]-y2;x2=pos[0];y2=pos[1];}
72
+ function getOffset()
73
+ {return[ox,oy];}
74
+ function moveOffset(offset)
75
+ {var ox=offset[0],oy=offset[1];if(0>x1+ox){ox-=ox+x1;}
76
+ if(0>y1+oy){oy-=oy+y1;}
77
+ if(boundy<y2+oy){oy+=boundy-(y2+oy);}
78
+ if(boundx<x2+ox){ox+=boundx-(x2+ox);}
79
+ x1+=ox;x2+=ox;y1+=oy;y2+=oy;}
80
+ function getCorner(ord)
81
+ {var c=getFixed();switch(ord){case'ne':return[c.x2,c.y];case'nw':return[c.x,c.y];case'se':return[c.x2,c.y2];case'sw':return[c.x,c.y2];}}
82
+ function getFixed()
83
+ {if(!options.aspectRatio){return getRect();}
84
+ var aspect=options.aspectRatio,min_x=options.minSize[0]/xscale,max_x=options.maxSize[0]/xscale,max_y=options.maxSize[1]/yscale,rw=x2-x1,rh=y2-y1,rwa=Math.abs(rw),rha=Math.abs(rh),real_ratio=rwa/rha,xx,yy;if(max_x===0){max_x=boundx*10;}
85
+ if(max_y===0){max_y=boundy*10;}
86
+ if(real_ratio<aspect){yy=y2;w=rha*aspect;xx=rw<0?x1-w:w+x1;if(xx<0){xx=0;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}else if(xx>boundx){xx=boundx;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}}else{xx=x2;h=rwa/aspect;yy=rh<0?y1-h:y1+h;if(yy<0){yy=0;w=Math.abs((yy-y1)*aspect);xx=rw<0?x1-w:w+x1;}else if(yy>boundy){yy=boundy;w=Math.abs(yy-y1)*aspect;xx=rw<0?x1-w:w+x1;}}
87
+ if(xx>x1){if(xx-x1<min_x){xx=x1+min_x;}else if(xx-x1>max_x){xx=x1+max_x;}
88
+ if(yy>y1){yy=y1+(xx-x1)/aspect;}else{yy=y1-(xx-x1)/aspect;}}else if(xx<x1){if(x1-xx<min_x){xx=x1-min_x;}else if(x1-xx>max_x){xx=x1-max_x;}
89
+ if(yy>y1){yy=y1+(x1-xx)/aspect;}else{yy=y1-(x1-xx)/aspect;}}
90
+ if(xx<0){x1-=xx;xx=0;}else if(xx>boundx){x1-=xx-boundx;xx=boundx;}
91
+ if(yy<0){y1-=yy;yy=0;}else if(yy>boundy){y1-=yy-boundy;yy=boundy;}
92
+ return makeObj(flipCoords(x1,y1,xx,yy));}
93
+ function rebound(p)
94
+ {if(p[0]<0){p[0]=0;}
95
+ if(p[1]<0){p[1]=0;}
96
+ if(p[0]>boundx){p[0]=boundx;}
97
+ if(p[1]>boundy){p[1]=boundy;}
98
+ return[p[0],p[1]];}
99
+ function flipCoords(x1,y1,x2,y2)
100
+ {var xa=x1,xb=x2,ya=y1,yb=y2;if(x2<x1){xa=x2;xb=x1;}
101
+ if(y2<y1){ya=y2;yb=y1;}
102
+ return[Math.round(xa),Math.round(ya),Math.round(xb),Math.round(yb)];}
103
+ function getRect()
104
+ {var xsize=x2-x1,ysize=y2-y1,delta;if(xlimit&&(Math.abs(xsize)>xlimit)){x2=(xsize>0)?(x1+xlimit):(x1-xlimit);}
105
+ if(ylimit&&(Math.abs(ysize)>ylimit)){y2=(ysize>0)?(y1+ylimit):(y1-ylimit);}
106
+ if(ymin/yscale&&(Math.abs(ysize)<ymin/yscale)){y2=(ysize>0)?(y1+ymin/yscale):(y1-ymin/yscale);}
107
+ if(xmin/xscale&&(Math.abs(xsize)<xmin/xscale)){x2=(xsize>0)?(x1+xmin/xscale):(x1-xmin/xscale);}
108
+ if(x1<0){x2-=x1;x1-=x1;}
109
+ if(y1<0){y2-=y1;y1-=y1;}
110
+ if(x2<0){x1-=x2;x2-=x2;}
111
+ if(y2<0){y1-=y2;y2-=y2;}
112
+ if(x2>boundx){delta=x2-boundx;x1-=delta;x2-=delta;}
113
+ if(y2>boundy){delta=y2-boundy;y1-=delta;y2-=delta;}
114
+ if(x1>boundx){delta=x1-boundy;y2-=delta;y1-=delta;}
115
+ if(y1>boundy){delta=y1-boundy;y2-=delta;y1-=delta;}
116
+ return makeObj(flipCoords(x1,y1,x2,y2));}
117
+ function makeObj(a)
118
+ {return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]};}
119
+ return{flipCoords:flipCoords,setPressed:setPressed,setCurrent:setCurrent,getOffset:getOffset,moveOffset:moveOffset,getCorner:getCorner,getFixed:getFixed};}());var Tracker=(function(){var onMove=function(){},onDone=function(){},trackDoc=options.trackDocument;function toFront()
120
+ {$trk.css({zIndex:450});if(trackDoc){$(document).bind('mousemove',trackMove).bind('mouseup',trackUp);}}
121
+ function toBack()
122
+ {$trk.css({zIndex:290});if(trackDoc){$(document).unbind('mousemove',trackMove).unbind('mouseup',trackUp);}}
123
+ function trackMove(e)
124
+ {onMove(mouseAbs(e));return false;}
125
+ function trackUp(e)
126
+ {e.preventDefault();e.stopPropagation();if(btndown){btndown=false;onDone(mouseAbs(e));if(Selection.isAwake()){options.onSelect.call(api,unscale(Coords.getFixed()));}
127
+ toBack();onMove=function(){};onDone=function(){};}
128
+ return false;}
129
+ function activateHandlers(move,done)
130
+ {btndown=true;onMove=move;onDone=done;toFront();return false;}
131
+ function trackTouchMove(e)
132
+ {e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return trackMove(e);}
133
+ function trackTouchEnd(e)
134
+ {e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return trackUp(e);}
135
+ function setCursor(t)
136
+ {$trk.css('cursor',t);}
137
+ if(Touch.support){$trk.bind('touchmove',trackTouchMove).bind('touchend',trackTouchEnd);}
138
+ if(!trackDoc){$trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);}
139
+ $img.before($trk);return{trackTouchMove:trackTouchMove,activateHandlers:activateHandlers,setCursor:setCursor};}());var Selection=(function(){var awake,hdep=370;var borders={};var handle={};var seehandles=false;var hhs=options.handleOffset;function insertBorder(type)
140
+ {var jq=$('<div />').css({position:'absolute',opacity:options.borderOpacity}).addClass(cssClass(type));$img_holder.append(jq);return jq;}
141
+ function dragDiv(ord,zi)
142
+ {var jq=$('<div />').mousedown(createDragger(ord)).css({cursor:ord+'-resize',position:'absolute',zIndex:zi});if(Touch.support){jq.bind('touchstart',Touch.createDragger(ord)).bind('touchmove',Tracker.trackTouchMove).bind('touchend',Tracker.trackTouchEnd);}
143
+ $hdl_holder.append(jq);return jq;}
144
+ function insertHandle(ord)
145
+ {return dragDiv(ord,hdep++).css({top:px(-hhs+1),left:px(-hhs+1),opacity:options.handleOpacity}).addClass(cssClass('handle'));}
146
+ function insertDragbar(ord)
147
+ {var s=options.handleSize,h=s,w=s,t=hhs,l=hhs;switch(ord){case'n':case's':w=pct(100);break;case'e':case'w':h=pct(100);break;}
148
+ return dragDiv(ord,hdep++).width(w).height(h).css({top:px(-t+1),left:px(-l+1)});}
149
+ function createHandles(li)
150
+ {var i;for(i=0;i<li.length;i++){handle[li[i]]=insertHandle(li[i]);}}
151
+ function moveHandles(c)
152
+ {var midvert=Math.round((c.h/2)-hhs),midhoriz=Math.round((c.w/2)-hhs),north=-hhs+1,west=-hhs+1,east=c.w-hhs,south=c.h-hhs,x,y;if(handle.e){handle.e.css({top:px(midvert),left:px(east)});handle.w.css({top:px(midvert)});handle.s.css({top:px(south),left:px(midhoriz)});handle.n.css({left:px(midhoriz)});}
153
+ if(handle.ne){handle.ne.css({left:px(east)});handle.se.css({top:px(south),left:px(east)});handle.sw.css({top:px(south)});}
154
+ if(handle.b){handle.b.css({top:px(south)});handle.r.css({left:px(east)});}}
155
+ function moveto(x,y)
156
+ {$img2.css({top:px(-y),left:px(-x)});$sel.css({top:px(y),left:px(x)});}
157
+ function resize(w,h)
158
+ {$sel.width(w).height(h);}
159
+ function refresh()
160
+ {var c=Coords.getFixed();Coords.setPressed([c.x,c.y]);Coords.setCurrent([c.x2,c.y2]);updateVisible();}
161
+ function updateVisible()
162
+ {if(awake){return update();}}
163
+ function update()
164
+ {var c=Coords.getFixed();resize(c.w,c.h);moveto(c.x,c.y);if(seehandles){moveHandles(c);}
165
+ if(!awake){show();}
166
+ options.onChange.call(api,unscale(c));}
167
+ function show()
168
+ {$sel.show();if(options.bgFade){$img.fadeTo(options.fadeTime,bgopacity);}else{$img.css('opacity',bgopacity);}
169
+ awake=true;}
170
+ function release()
171
+ {disableHandles();$sel.hide();if(options.bgFade){$img.fadeTo(options.fadeTime,1);}else{$img.css('opacity',1);}
172
+ awake=false;options.onRelease.call(api);}
173
+ function showHandles()
174
+ {if(seehandles){moveHandles(Coords.getFixed());$hdl_holder.show();}}
175
+ function enableHandles()
176
+ {seehandles=true;if(options.allowResize){moveHandles(Coords.getFixed());$hdl_holder.show();return true;}}
177
+ function disableHandles()
178
+ {seehandles=false;$hdl_holder.hide();}
179
+ function animMode(v)
180
+ {if(animating===v){disableHandles();}else{enableHandles();}}
181
+ function done()
182
+ {animMode(false);refresh();}
183
+ if(options.drawBorders){borders={top:insertBorder('hline'),bottom:insertBorder('hline bottom'),left:insertBorder('vline'),right:insertBorder('vline right')};}
184
+ if(options.dragEdges){handle.t=insertDragbar('n');handle.b=insertDragbar('s');handle.r=insertDragbar('e');handle.l=insertDragbar('w');}
185
+ if(options.sideHandles){createHandles(['n','s','e','w']);}
186
+ if(options.cornerHandles){createHandles(['sw','nw','ne','se']);}
187
+ var $track=newTracker().mousedown(createDragger('move')).css({cursor:'move',position:'absolute',zIndex:360});if(Touch.support){$track.bind('touchstart.jcrop',Touch.createDragger('move')).bind('touchmove',Tracker.trackTouchMove).bind('touchend',Tracker.trackTouchEnd);}
188
+ $img_holder.append($track);disableHandles();return{updateVisible:updateVisible,update:update,release:release,refresh:refresh,isAwake:function(){return awake;},setCursor:function(cursor){$track.css('cursor',cursor);},enableHandles:enableHandles,enableOnly:function(){seehandles=true;},showHandles:showHandles,disableHandles:disableHandles,animMode:animMode,done:done};}());var KeyManager=(function(){var $keymgr=$('<input type="radio" />').css({position:'fixed',left:'-120px',width:'12px'}),$keywrap=$('<div />').css({position:'absolute',overflow:'hidden'}).append($keymgr);function watchKeys()
189
+ {if(options.keySupport){$keymgr.show();$keymgr.focus();}}
190
+ function onBlur(e)
191
+ {$keymgr.hide();}
192
+ function doNudge(e,x,y)
193
+ {if(options.allowMove){Coords.moveOffset([x,y]);Selection.updateVisible();}
194
+ e.preventDefault();e.stopPropagation();}
195
+ function parseKey(e)
196
+ {if(e.ctrlKey){return true;}
197
+ shift_down=e.shiftKey?true:false;var nudge=shift_down?10:1;switch(e.keyCode){case 37:doNudge(e,-nudge,0);break;case 39:doNudge(e,nudge,0);break;case 38:doNudge(e,0,-nudge);break;case 40:doNudge(e,0,nudge);break;case 27:Selection.release();break;case 9:return true;}
198
+ return false;}
199
+ if(options.keySupport){$keymgr.keydown(parseKey).blur(onBlur);if(ie6mode||!options.fixedSupport){$keymgr.css({position:'absolute',left:'-20px'});$keywrap.append($keymgr).insertBefore($img);}else{$keymgr.insertBefore($img);}}
200
+ return{watchKeys:watchKeys};}());function setClass(cname)
201
+ {$div.removeClass().addClass(cssClass('holder')).addClass(cname);}
202
+ function animateTo(a,callback)
203
+ {var x1=parseInt(a[0],10)/xscale,y1=parseInt(a[1],10)/yscale,x2=parseInt(a[2],10)/xscale,y2=parseInt(a[3],10)/yscale;if(animating){return;}
204
+ var animto=Coords.flipCoords(x1,y1,x2,y2),c=Coords.getFixed(),initcr=[c.x,c.y,c.x2,c.y2],animat=initcr,interv=options.animationDelay,ix1=animto[0]-initcr[0],iy1=animto[1]-initcr[1],ix2=animto[2]-initcr[2],iy2=animto[3]-initcr[3],pcent=0,velocity=options.swingSpeed;x=animat[0];y=animat[1];x2=animat[2];y2=animat[3];Selection.animMode(true);var anim_timer;function queueAnimator(){window.setTimeout(animator,interv);}
205
+ var animator=(function(){return function(){pcent+=(100-pcent)/velocity;animat[0]=x+((pcent/100)*ix1);animat[1]=y+((pcent/100)*iy1);animat[2]=x2+((pcent/100)*ix2);animat[3]=y2+((pcent/100)*iy2);if(pcent>=99.8){pcent=100;}
206
+ if(pcent<100){setSelectRaw(animat);queueAnimator();}else{Selection.done();if(typeof(callback)==='function'){callback.call(api);}}};}());queueAnimator();}
207
+ function setSelect(rect)
208
+ {setSelectRaw([parseInt(rect[0],10)/xscale,parseInt(rect[1],10)/yscale,parseInt(rect[2],10)/xscale,parseInt(rect[3],10)/yscale]);}
209
+ function setSelectRaw(l)
210
+ {Coords.setPressed([l[0],l[1]]);Coords.setCurrent([l[2],l[3]]);Selection.update();}
211
+ function tellSelect()
212
+ {return unscale(Coords.getFixed());}
213
+ function tellScaled()
214
+ {return Coords.getFixed();}
215
+ function setOptionsNew(opt)
216
+ {setOptions(opt);interfaceUpdate();}
217
+ function disableCrop()
218
+ {options.disabled=true;Selection.disableHandles();Selection.setCursor('default');Tracker.setCursor('default');}
219
+ function enableCrop()
220
+ {options.disabled=false;interfaceUpdate();}
221
+ function cancelCrop()
222
+ {Selection.done();Tracker.activateHandlers(null,null);}
223
+ function destroy()
224
+ {$div.remove();$origimg.show();$(obj).removeData('Jcrop');}
225
+ function setImage(src,callback)
226
+ {Selection.release();disableCrop();var img=new Image();img.onload=function(){var iw=img.width;var ih=img.height;var bw=options.boxWidth;var bh=options.boxHeight;$img.width(iw).height(ih);$img.attr('src',src);$img2.attr('src',src);presize($img,bw,bh);boundx=$img.width();boundy=$img.height();$img2.width(boundx).height(boundy);$trk.width(boundx+(bound*2)).height(boundy+(bound*2));$div.width(boundx).height(boundy);enableCrop();if(typeof(callback)==='function'){callback.call(api);}};img.src=src;}
227
+ function interfaceUpdate(alt)
228
+ {if(options.allowResize){if(alt){Selection.enableOnly();}else{Selection.enableHandles();}}else{Selection.disableHandles();}
229
+ Tracker.setCursor(options.allowSelect?'crosshair':'default');Selection.setCursor(options.allowMove?'move':'default');if(options.hasOwnProperty('setSelect')){setSelect(options.setSelect);Selection.done();delete(options.setSelect);}
230
+ if(options.hasOwnProperty('trueSize')){xscale=options.trueSize[0]/boundx;yscale=options.trueSize[1]/boundy;}
231
+ if(options.hasOwnProperty('bgColor')){if(supportsColorFade()&&options.fadeTime){$div.animate({backgroundColor:options.bgColor},{queue:false,duration:options.fadeTime});}else{$div.css('backgroundColor',options.bgColor);}
232
+ delete(options.bgColor);}
233
+ if(options.hasOwnProperty('bgOpacity')){bgopacity=options.bgOpacity;if(Selection.isAwake()){if(options.fadeTime){$img.fadeTo(options.fadeTime,bgopacity);}else{$div.css('opacity',options.opacity);}}
234
+ delete(options.bgOpacity);}
235
+ xlimit=options.maxSize[0]||0;ylimit=options.maxSize[1]||0;xmin=options.minSize[0]||0;ymin=options.minSize[1]||0;if(options.hasOwnProperty('outerImage')){$img.attr('src',options.outerImage);delete(options.outerImage);}
236
+ Selection.refresh();}
237
+ if(Touch.support){$trk.bind('touchstart',Touch.newSelection);}
238
+ $hdl_holder.hide();interfaceUpdate(true);var api={setImage:setImage,animateTo:animateTo,setSelect:setSelect,setOptions:setOptionsNew,tellSelect:tellSelect,tellScaled:tellScaled,setClass:setClass,disable:disableCrop,enable:enableCrop,cancel:cancelCrop,release:Selection.release,destroy:destroy,focus:KeyManager.watchKeys,getBounds:function(){return[boundx*xscale,boundy*yscale];},getWidgetSize:function(){return[boundx,boundy];},getScaleFactor:function(){return[xscale,yscale];},ui:{holder:$div,selection:$sel}};if($.browser.msie){$div.bind('selectstart',function(){return false;});}
239
+ $origimg.data('Jcrop',api);return api;};$.fn.Jcrop=function(options,callback)
240
+ {function attachWhenDone(from)
241
+ {var opt=(typeof(options)==='object')?options:{};var loadsrc=opt.useImg||from.src;var img=new Image();img.onload=function(){function attachJcrop(){var api=$.Jcrop(from,opt);if(typeof(callback)==='function'){callback.call(api);}}
242
+ function attachAttempt(){if(!img.width||!img.height){window.setTimeout(attachAttempt,50);}else{attachJcrop();}}
243
+ window.setTimeout(attachAttempt,50);};img.src=loadsrc;}
244
+ this.each(function(){if($(this).data('Jcrop')){if(options==='api'){return $(this).data('Jcrop');}
245
+ else{$(this).data('Jcrop').setOptions(options);}}
246
+ else{attachWhenDone(this);}});return this;};$.Jcrop.defaults={allowSelect:true,allowMove:true,allowResize:true,trackDocument:true,baseClass:'jcrop',addClass:null,bgColor:'black',bgOpacity:0.6,bgFade:false,borderOpacity:0.4,handleOpacity:0.5,handleSize:9,handleOffset:5,aspectRatio:0,keySupport:true,cornerHandles:true,sideHandles:true,drawBorders:true,dragEdges:true,fixedSupport:true,touchSupport:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onRelease:function(){}};}(jQuery));
@@ -0,0 +1,519 @@
1
+ /**
2
+ * Smart Auto Complete plugin
3
+ *
4
+ * Copyright (c) 2011 Lakshan Perera (laktek.com)
5
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
6
+ *
7
+ */
8
+
9
+ /*
10
+ Requirements: jQuery 1.5 or above
11
+
12
+ Usage:
13
+ $(target).smartAutoComplete({options})
14
+
15
+ Options:
16
+ minCharLimit: (integer) minimum characters user have to type before invoking the autocomplete (default: 1)
17
+ maxResults: (integer) maximum number of results to return (default: null (unlimited))
18
+ delay: (integer) delay before autocomplete starts (default: 0)
19
+ disabled: (boolean) whether autocomplete disabled on the field (default: false)
20
+ forceSelect: (boolean) If set to true, field will be always filled with best matching result, without leaving the custom input.
21
+ Better to enable this option, if you want autocomplete field to behave similar to a HTML select field. (Check Example 2 in the demo)
22
+ (default: false)
23
+ typeAhead: (boolean) If set to true, it will offer the best matching result in grey within the field; that can be auto-completed by pressing the right arrow-key or enter.
24
+ This is similar to behaviour in Google Instant Search's query field (Check Example 3 in the demo)
25
+ (default: false)
26
+ source: (string/array) you can supply an array with items or a string containing a URL to fetch items for the source
27
+ this is optional if you prefer to have your own filter method
28
+ filter: (function) define a custom function that would return matching items to the entered text (this will override the default filtering algorithm)
29
+ should return an array or a Deferred object (ajax call)
30
+ parameters available: term, source
31
+ resultFormatter: (function) the function you supply here will be called to format the output of an individual result.
32
+ should return a string
33
+ parameters available: result
34
+ resultsContainer: (selector) to which element(s) the result should be appended.
35
+ resultElement: (selector) references to the result elements collection (e.g. li, div.result)
36
+
37
+ Events:
38
+ keyIn: fires when user types into the field (parameters: query)
39
+ resultsReady: fires when the filter function returns (parameters: results)
40
+ showResults: fires when results are shown (parameters: results)
41
+ noResults: fires when filter returns an empty array
42
+ itemSelect: fires when user selects an item from the result list (paramters: item)
43
+ itemFocus: fires when user highlights an item with mouse or arrow keys (paramters: item)
44
+ itemUnfocus: fires when user moves out from an highlighted item (paramters: item)
45
+ lostFocus: fires when autocomplete field loses focus by user clicking outside of the field or focusing on another field. Also, this event is fired when a value is selected
46
+
47
+ })
48
+ */
49
+
50
+ (function($){
51
+ $.fn.smartAutoComplete = function(){
52
+
53
+ if(arguments.length < 1){
54
+ // get the smart autocomplete object of the first element and return
55
+ var first_element = this[0];
56
+ return $(first_element).data("smart-autocomplete")
57
+ }
58
+
59
+ var default_filter_matcher = function(term, source, context){
60
+ var matcher = new RegExp(term.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i" );
61
+
62
+ return $.grep(source, function(value) {
63
+ return matcher.test( value );
64
+ });
65
+
66
+ }
67
+
68
+ var default_options = {
69
+ minCharLimit: 1,
70
+ maxResults: null,
71
+ delay: 0,
72
+ disabled: false,
73
+ forceSelect: false,
74
+ typeAhead: false,
75
+ resultElement: "li",
76
+
77
+ resultFormatter: function(r){ return ("<li>" + r + "</li>"); },
78
+
79
+ filter: function(term, source){
80
+ var context = this;
81
+ var options = $(context).data('smart-autocomplete');
82
+
83
+
84
+ //when source is an array
85
+ if($.type(source) === "array") {
86
+ // directly map
87
+ var results = default_filter_matcher(term, source, context);
88
+ return results;
89
+ }
90
+ //when source is a string
91
+ else if($.type(source) === "string"){
92
+ // treat the string as a URL endpoint
93
+ // pass the query as 'term'
94
+
95
+ return $.Deferred(function(dfd){
96
+ $.ajax({
97
+ url: source,
98
+ data: {"term": term},
99
+ dataType: "json"
100
+ }).success( function(data){
101
+ dfd.resolve( default_filter_matcher(term, data, context) );
102
+ });
103
+ }).promise();
104
+
105
+ }
106
+
107
+ },
108
+
109
+ alignResultsContainer: false,
110
+
111
+ clearResults: function(){
112
+ //remove type ahead field
113
+ $(this.context).prev(".smart_autocomplete_type_ahead_field").remove();
114
+ $(this.context).css({ background: '#FFF' });
115
+
116
+ //clear results div
117
+ $(this.resultsContainer).html("");
118
+ },
119
+
120
+ setCurrentSelectionToContext: function(){
121
+ if(this.rawResults.length > 0 && this.currentSelection >= 0)
122
+ $(this.context).val(this.rawResults[(this.currentSelection)]);
123
+ },
124
+
125
+ setItemSelected: function(val){
126
+ this.itemSelected = val;
127
+ }
128
+
129
+ };
130
+
131
+ //define the default events
132
+ $.event.special.keyIn = {
133
+ setup: function(){ return false; },
134
+
135
+ _default: function(ev){
136
+ var context = ev.target;
137
+ var options = $(context).data("smart-autocomplete");
138
+ var source = options.source || null;
139
+ var filter = options.filter;
140
+
141
+ //event specific data
142
+ var query = ev.smartAutocompleteData.query;
143
+
144
+ if(options.disabled)
145
+ return false;
146
+
147
+ //set item selected property
148
+ options.setItemSelected(false);
149
+
150
+ //call the filter function with delay
151
+ setTimeout(function(){
152
+ $.when( filter.apply(options, [query, options.source]) ).done(function( results ){
153
+ //do the trimming
154
+ var trimmed_results = (options.maxResults > 0 ? results.splice(0, options.maxResults) : results);
155
+
156
+ $(context).trigger('resultsReady', [trimmed_results]);
157
+ });
158
+ }, options.delay);
159
+ }
160
+ };
161
+
162
+ $.event.special.resultsReady = {
163
+ setup: function(){ return false },
164
+
165
+ _default: function(ev){
166
+ var context = ev.target;
167
+ var options = $(context).data("smart-autocomplete");
168
+
169
+ //event specific data
170
+ var results = ev.smartAutocompleteData.results;
171
+
172
+ //exit if smart complete is disabled
173
+ if(options.disabled)
174
+ return false;
175
+
176
+ //clear all previous results
177
+ $(context).smartAutoComplete().clearResults();
178
+
179
+ //save the raw results
180
+ options.rawResults = results;
181
+
182
+ //fire the no match event and exit if no matching results
183
+ if(results.length < 1){
184
+ $(context).trigger('noResults');
185
+ return false
186
+ }
187
+
188
+ //call the results formatter function
189
+ var formatted_results = $.map(results, function(result){
190
+ return options.resultFormatter.apply(options, [result]);
191
+ });
192
+
193
+ var formatted_results_html = formatted_results.join("");
194
+
195
+ //append the results to the container
196
+ if(options.resultsContainer)
197
+ $(options.resultsContainer).append(formatted_results_html);
198
+
199
+ //trigger results ready event
200
+ $(context).trigger('showResults', [results]);
201
+ }
202
+ };
203
+
204
+ $.event.special.showResults = {
205
+ setup: function(){ return false },
206
+
207
+ _default: function(ev){
208
+ var context = ev.target;
209
+ var options = $(context).data("smart-autocomplete");
210
+ var results_container = $(options.resultsContainer);
211
+
212
+ //event specific data
213
+ var raw_results = ev.smartAutocompleteData.results;
214
+
215
+ //type ahead
216
+ if(options.typeAhead && (raw_results[0].substr(0, $(context).val().length) == $(context).val()) ){
217
+ var suggestion = raw_results[0]; //options.typeAheadExtractor($(context).val(), raw_results[0]);
218
+
219
+ //add new typeAhead field
220
+ $(context).before("<input class='smart_autocomplete_type_ahead_field' type='text' autocomplete='off' disabled='disabled' value='" + suggestion + "'/>");
221
+
222
+ $(context).css({
223
+ position: "relative",
224
+ zIndex: 2,
225
+ background: 'transparent'
226
+ });
227
+
228
+ var typeAheadField = $(context).prev("input");
229
+ typeAheadField.css({
230
+ position: "absolute",
231
+ zIndex: 1,
232
+ overflow: 'hidden',
233
+ background: 'none repeat scroll 0 0 #FFFFFF',
234
+ borderColor: 'transparent',
235
+ width: $(context).width(),
236
+ color: 'silver'
237
+ });
238
+
239
+ //trigger item over for first item
240
+ options.currentSelection = 0;
241
+ if(results_container)
242
+ $(context).trigger('itemFocus', results_container.children()[options.currentSelection]);
243
+ }
244
+
245
+ //show the results container after aligning it with the field
246
+ if(results_container){
247
+ if(options.alignResultsContainer){
248
+ results_container.css({
249
+ position: "absolute",
250
+ top: function(){ return $(context).offset().top + $(context).height(); },
251
+ left: function(){ return $(context).offset().left; },
252
+ width: function(){ return $(context).width(); },
253
+ zIndex: 1000
254
+ })
255
+ }
256
+ results_container.show();
257
+ }
258
+
259
+ }
260
+ };
261
+
262
+ $.event.special.noResults = {
263
+ setup: function(){ return false },
264
+
265
+ _default: function(ev){
266
+ var context = ev.target;
267
+ var options = $(context).data("smart-autocomplete");
268
+ var result_container = $(options.resultsContainer);
269
+
270
+ if(result_container){
271
+ //clear previous results
272
+ options.clearResults();
273
+ }
274
+
275
+ }
276
+ };
277
+
278
+ $.event.special.itemSelect = {
279
+ setup: function(){ return false },
280
+
281
+ _default: function(ev){
282
+ var context = ev.target;
283
+ var options = $(context).data("smart-autocomplete");
284
+
285
+ //event specific data
286
+ var selected_item = ev.smartAutocompleteData.item;
287
+
288
+ //get the text from selected item
289
+ var selected_value = $(selected_item).text() || $(selected_item).val();
290
+ //set it as the value of the autocomplete field
291
+ $(context).val(selected_value);
292
+
293
+ //set item selected property
294
+ options.setItemSelected(true);
295
+
296
+ //set number of current chars in field
297
+ options.originalCharCount = $(context).val().length;
298
+
299
+ //trigger lost focus
300
+ $(context).trigger('lostFocus');
301
+ }
302
+ };
303
+
304
+ $.event.special.itemFocus = {
305
+ setup: function(){ return false },
306
+
307
+ _default: function(ev){
308
+
309
+ //event specific data
310
+ var item = ev.smartAutocompleteData.item;
311
+
312
+ $(item).addClass("smart_autocomplete_highlight");
313
+ }
314
+ };
315
+
316
+ $.event.special.itemUnfocus = {
317
+ setup: function(){ return false },
318
+
319
+ _default: function(ev){
320
+
321
+ //event specific data
322
+ var item = ev.smartAutocompleteData.item;
323
+
324
+ $(item).removeClass("smart_autocomplete_highlight");
325
+ }
326
+ }
327
+
328
+ $.event.special.lostFocus = {
329
+ setup: function(){ return false },
330
+
331
+ _default: function(ev){
332
+ var context = ev.target;
333
+ var options = $(context).data("smart-autocomplete");
334
+
335
+ //if force select is selected and no item is selected, clear currently entered text
336
+ if(options.forceSelect && !options.itemSelected)
337
+ $(options.context).val("");
338
+
339
+ //clear results
340
+ options.clearResults();
341
+
342
+ //hide the results container
343
+ if(options.resultsContainer)
344
+ $(options.resultsContainer).hide();
345
+
346
+ //set current selection to null
347
+ options.currentSelection = null;
348
+ }
349
+ };
350
+
351
+ var passed_options = arguments[0];
352
+
353
+ return this.each(function(i) {
354
+ //set the options
355
+ var options = $.extend(default_options, $(this).data("smart-autocomplete"), passed_options);
356
+ //set the context
357
+ options['context'] = this;
358
+
359
+ //if a result container is not defined
360
+ if($.type(options.resultsContainer) === 'undefined' ){
361
+ //define the default result container if it is already not defined
362
+ var default_container = $("<ul class='smart_autocomplete_container' style='display:none'></ul>");
363
+ default_container.appendTo("body");
364
+
365
+ options.resultsContainer = default_container;
366
+ options.alignResultsContainer = true;
367
+ }
368
+
369
+ $(this).data("smart-autocomplete", options);
370
+
371
+ // bind user events
372
+ $(this).keyup(function(ev){
373
+ //get the options
374
+ var options = $(this).data("smart-autocomplete");
375
+
376
+ //up arrow
377
+ if(ev.keyCode == '38'){
378
+
379
+ if(options.resultsContainer){
380
+ var current_selection = options.currentSelection || 0;
381
+ var result_suggestions = $(options.resultsContainer).children();
382
+
383
+ if(current_selection >= 0)
384
+ $(options.context).trigger('itemUnfocus', result_suggestions[current_selection] );
385
+
386
+ if(--current_selection <= 0)
387
+ current_selection = 0;
388
+
389
+ options['currentSelection'] = current_selection;
390
+
391
+ $(options.context).trigger('itemFocus', [ result_suggestions[current_selection] ] );
392
+ }
393
+ }
394
+
395
+ //down arrow
396
+ else if(ev.keyCode == '40'){
397
+
398
+ if(options.resultsContainer){
399
+ var current_selection = options.currentSelection;
400
+ var result_suggestions = $(options.resultsContainer).children();
401
+
402
+ if(current_selection >= 0)
403
+ $(options.context).trigger('itemUnfocus', result_suggestions[current_selection] );
404
+
405
+ if(isNaN(current_selection) || (++current_selection >= result_suggestions.length) )
406
+ current_selection = 0;
407
+
408
+ options['currentSelection'] = current_selection;
409
+
410
+ $(options.context).trigger('itemFocus', [ result_suggestions[current_selection] ] );
411
+ }
412
+
413
+ }
414
+
415
+ //right arrow & enter key
416
+ else if(ev.keyCode == '39' || ev.keyCode == '13'){
417
+ var type_ahead_field = $(options.context).prev('.smart_autocomplete_type_ahead_field');
418
+ if(options.resultsContainer && $(options.resultsContainer).is(':visible')){
419
+ var current_selection = options.currentSelection;
420
+ var result_suggestions = $(options.resultsContainer).children();
421
+
422
+ $(options.context).trigger('itemSelect', [ result_suggestions[current_selection] ] );
423
+ }
424
+ else if(options.typeAhead && type_ahead_field.is(':visible'))
425
+ $(options.context).trigger('itemSelect', [ type_ahead_field ] );
426
+
427
+ return false;
428
+ }
429
+
430
+ else {
431
+ var current_char_count = $(options.context).val().length;
432
+ //check whether the string has modified
433
+ if(options.originalCharCount == current_char_count)
434
+ return;
435
+
436
+ //check minimum number of characters are typed
437
+ if(current_char_count >= options.minCharLimit){
438
+ $(options.context).trigger('keyIn', [$(this).val()]);
439
+ }
440
+ else{
441
+ if($(options.resultsContainer).is(':visible')){
442
+ options.currentSelection = null;
443
+ $(options.context).trigger('lostFocus');
444
+ }
445
+ }
446
+
447
+ }
448
+ });
449
+
450
+ $(this).focus(function(){
451
+ //if the field is in a form capture the return key event
452
+ $(this).closest("form").bind("keydown.block_for_smart_autocomplete", function(ev){
453
+ var type_ahead_field = $(options.context).prev('.smart_autocomplete_type_ahead_field');
454
+ if(ev.keyCode == '13'){
455
+ if(options.resultsContainer && $(options.resultsContainer).is(':visible')){
456
+ var current_selection = options.currentSelection;
457
+ var result_suggestions = $(options.resultsContainer).children();
458
+
459
+ $(options.context).trigger('itemSelect', [ result_suggestions[current_selection] ] );
460
+ return false;
461
+ }
462
+ else if(options.typeAhead && type_ahead_field.is(':visible') ){
463
+ $(options.context).trigger('itemSelect', [ type_ahead_field ] );
464
+ return false;
465
+ }
466
+ }
467
+ });
468
+
469
+ if(options.forceSelect){
470
+ $(this).select();
471
+ }
472
+ });
473
+
474
+ //check for loosing focus on smart complete field and results container
475
+ $(document).bind("focusin click", function(ev){
476
+ if($(options.resultsContainer).is(':visible')){
477
+ var elemIsParent = $.contains(options.resultsContainer[0], ev.target);
478
+ if(ev.target == options.resultsContainer[0] || ev.target == options.context || elemIsParent) return
479
+
480
+ $(options.context).closest("form").unbind("keydown.block_for_smart_autocomplete");
481
+ $(options.context).trigger('lostFocus');
482
+ }
483
+ });
484
+
485
+ //bind events to results container
486
+ $(options.resultsContainer).delegate(options.resultElement, 'mouseenter.smart_autocomplete', function(){
487
+ var current_selection = options.currentSelection || 0;
488
+ var result_suggestions = $(options.resultsContainer).children();
489
+
490
+ options['currentSelection'] = $(this).prevAll().length;
491
+
492
+ $(options.context).trigger('itemFocus', [this] );
493
+
494
+ });
495
+
496
+ $(options.resultsContainer).delegate(options.resultElement, 'mouseleave.smart_autocomplete', function(){
497
+ $(options.context).trigger('itemUnfocus', [this] );
498
+ });
499
+
500
+ $(options.resultsContainer).delegate(options.resultElement, 'click.smart_autocomplete', function(){
501
+ $(options.context).trigger('itemSelect', [this]);
502
+ return false
503
+ });
504
+
505
+ //bind plugin specific events
506
+ $(this).bind({
507
+ keyIn: function(ev, query){ ev.smartAutocompleteData = {'query': query }; },
508
+ resultsReady: function(ev, results){ ev.smartAutocompleteData = {'results': results }; },
509
+ showResults: function(ev, results){ ev.smartAutocompleteData = {'results': results } },
510
+ noResults: function(){},
511
+ lostFocus: function(){},
512
+ itemSelect: function(ev, item){ ev.smartAutocompleteData = {'item': item }; },
513
+ itemFocus: function(ev, item){ ev.smartAutocompleteData = {'item': item }; },
514
+ itemUnfocus: function(ev, item){ ev.smartAutocompleteData = {'item': item }; }
515
+ });
516
+ });
517
+
518
+ }
519
+ })(jQuery);