spiderfw 0.5.19 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/CHANGELOG +7 -0
  2. data/VERSION +1 -1
  3. data/apps/core/auth/lib/rbac.rb +7 -2
  4. data/apps/core/auth/models/mixins/rbac_provider.rb +66 -4
  5. data/apps/core/components/assets.rb +63 -33
  6. data/apps/core/components/public/js/jquery/{jquery-1.4.3.js → jquery-1.5.2.js} +2617 -1126
  7. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.apple.js +155 -0
  8. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/overlay/overlay.js +293 -0
  9. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/scrollable/scrollable.js +335 -0
  10. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.css +59 -0
  11. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tabs/tabs.js +283 -0
  12. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/toolbox/toolbox.expose.js +224 -0
  13. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.dynamic.js +150 -0
  14. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.js +343 -0
  15. data/apps/core/components/public/js/jquery/jquery-tools-1.2.5/tooltip/tooltip.slide.js +78 -0
  16. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/button_bg.png +0 -0
  17. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/datepicker.gif +0 -0
  18. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/icon_sprite.png +0 -0
  19. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/progress_bar.gif +0 -0
  20. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_h_bg.gif +0 -0
  21. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_handles.png +0 -0
  22. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/slider_v_bg.gif +0 -0
  23. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/tab_bg.gif +0 -0
  24. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/the_gradient.gif +0 -0
  25. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-anim_basic_16x16.gif +0 -0
  26. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  27. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  28. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_flat_10_000000_40x100.png +0 -0
  29. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  30. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  31. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  32. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  33. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  34. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  35. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_222222_256x240.png +0 -0
  36. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_228ef1_256x240.png +0 -0
  37. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ef8c08_256x240.png +0 -0
  38. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffd27a_256x240.png +0 -0
  39. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/images/ui-icons_ffffff_256x240.png +0 -0
  40. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4 → jquery-ui-1.8.11}/css/Aristo/jquery-ui.custom.css +0 -0
  41. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-af.js +0 -0
  42. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ar-DZ.js +23 -0
  43. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ar.js +7 -8
  44. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-az.js +0 -0
  45. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bg.js +0 -0
  46. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-bs.js +0 -0
  47. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ca.js +0 -0
  48. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-cs.js +0 -0
  49. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-da.js +0 -0
  50. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-de.js +0 -0
  51. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-el.js +0 -0
  52. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-AU.js +23 -0
  53. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-en-GB.js +0 -0
  54. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-en-NZ.js +23 -0
  55. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eo.js +0 -0
  56. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-es.js +0 -0
  57. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-et.js +0 -0
  58. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-eu.js +0 -0
  59. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fa.js +0 -0
  60. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fi.js +0 -0
  61. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fo.js +0 -0
  62. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr-CH.js +0 -0
  63. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-fr.js +12 -10
  64. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-gl.js +23 -0
  65. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-he.js +0 -0
  66. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hr.js +0 -0
  67. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hu.js +1 -1
  68. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-hy.js +0 -0
  69. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-id.js +0 -0
  70. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-is.js +0 -0
  71. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-it.js +0 -0
  72. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ja.js +0 -0
  73. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ko.js +0 -0
  74. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-kz.js +23 -0
  75. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lt.js +0 -0
  76. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-lv.js +0 -0
  77. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-ml.js +23 -0
  78. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ms.js +0 -0
  79. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-nl.js +0 -0
  80. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-no.js +23 -0
  81. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pl.js +0 -0
  82. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-pt-BR.js +0 -0
  83. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-pt.js +22 -0
  84. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-rm.js +21 -0
  85. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ro.js +0 -0
  86. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ru.js +1 -1
  87. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sk.js +0 -0
  88. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sl.js +0 -0
  89. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sq.js +0 -0
  90. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr-SR.js +0 -0
  91. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sr.js +0 -0
  92. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-sv.js +0 -0
  93. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-ta.js +0 -0
  94. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-th.js +1 -1
  95. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/i18n/jquery.ui.datepicker-tj.js +23 -0
  96. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-tr.js +0 -0
  97. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-uk.js +0 -0
  98. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-vi.js +0 -0
  99. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-CN.js +0 -0
  100. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-HK.js +0 -0
  101. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/i18n/jquery.ui.datepicker-zh-TW.js +0 -0
  102. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.blind.js +3 -3
  103. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.bounce.js +3 -3
  104. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.clip.js +3 -3
  105. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.core.js +48 -15
  106. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.drop.js +3 -3
  107. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.explode.js +2 -2
  108. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/jquery.effects.fade.js +32 -0
  109. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.fold.js +3 -3
  110. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.highlight.js +2 -2
  111. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.pulsate.js +2 -2
  112. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.scale.js +4 -4
  113. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.shake.js +3 -3
  114. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.slide.js +4 -4
  115. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.effects.transfer.js +2 -2
  116. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.accordion.js +33 -20
  117. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.autocomplete.js +104 -42
  118. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.button.js +35 -13
  119. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.core.js +111 -84
  120. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.datepicker.js +87 -46
  121. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.dialog.js +105 -75
  122. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.draggable.js +17 -15
  123. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.droppable.js +5 -5
  124. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.mouse.js +16 -11
  125. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.position.js +51 -32
  126. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.progressbar.js +24 -10
  127. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.resizable.js +7 -7
  128. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.selectable.js +3 -3
  129. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.slider.js +9 -7
  130. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.sortable.js +22 -20
  131. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.tabs.js +15 -14
  132. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → jquery-ui-1.8.11}/ui/jquery.ui.widget.js +50 -25
  133. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/GPL-LICENSE.txt +1 -1
  134. data/apps/core/components/public/js/jquery/{jquery-ui-1.8.4/development-bundle → plugins/bsmselect}/MIT-LICENSE.txt +3 -7
  135. data/apps/core/components/public/js/jquery/plugins/bsmselect/README.md +185 -0
  136. data/apps/core/components/public/js/jquery/plugins/bsmselect/css/jquery.bsmselect.css +64 -0
  137. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.compatibility.js +60 -0
  138. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +381 -0
  139. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.sortable.js +49 -0
  140. data/apps/core/components/public/js/plugins/sortable.js +16 -7
  141. data/apps/core/components/public/js/spider.js +60 -41
  142. data/apps/core/components/widgets/admin/admin.shtml +1 -1
  143. data/apps/core/components/widgets/list/list.shtml +2 -2
  144. data/apps/core/components/widgets/month_calendar/month_calendar.shtml +23 -20
  145. data/apps/core/components/widgets/switcher/switcher.rb +77 -21
  146. data/apps/core/components/widgets/switcher/templates/default.shtml +8 -0
  147. data/apps/core/components/widgets/switcher/templates/table.shtml +15 -0
  148. data/apps/core/components/widgets/table/table.rb +4 -1
  149. data/apps/core/components/widgets/table/table.shtml +10 -8
  150. data/apps/core/forms/public/css/form.css +9 -1
  151. data/apps/core/forms/public/date_time.js +14 -2
  152. data/apps/core/forms/public/input.js +1 -1
  153. data/apps/core/forms/public/select.js +4 -3
  154. data/apps/core/forms/tags/element_row.erb +11 -2
  155. data/apps/core/forms/widgets/inputs/date_time/date_time.rb +9 -0
  156. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -1
  157. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  158. data/apps/core/forms/widgets/inputs/input/input.rb +0 -3
  159. data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
  160. data/apps/messenger/backends/email/sendmail.rb +20 -0
  161. data/apps/messenger/backends/email/smtp.rb +12 -14
  162. data/apps/messenger/backends/email/test.rb +20 -0
  163. data/apps/messenger/config/options.rb +9 -9
  164. data/apps/messenger/config/test.config.yml +2 -0
  165. data/apps/messenger/controllers/mixins/messenger_helper.rb +41 -15
  166. data/apps/messenger/lib/email_backend.rb +10 -0
  167. data/apps/messenger/messenger.rb +45 -26
  168. data/apps/messenger/test/features/attachments.feature +26 -0
  169. data/apps/messenger/test/features/messenger_helper.feature +31 -0
  170. data/apps/messenger/test/features/sending_email.feature +10 -0
  171. data/apps/messenger/test/features/step_definitions/common_steps.rb +11 -0
  172. data/apps/messenger/test/features/step_definitions/email_steps.rb +98 -0
  173. data/apps/messenger/test/features/support/env.rb +11 -0
  174. data/apps/messenger/test/files/test_file1.txt +1 -0
  175. data/apps/messenger/test/lib/controllers/mail_test_controller.rb +34 -0
  176. data/apps/messenger/test/templates/email/multipart.html.erb +1 -0
  177. data/apps/messenger/test/templates/email/multipart.txt.erb +1 -0
  178. data/apps/messenger/test/templates/email/simple.erb +1 -0
  179. data/apps/messenger/test/templates/email/vars.erb +1 -0
  180. data/lib/spiderfw/cmd/cmd.rb +4 -0
  181. data/lib/spiderfw/cmd/commands/webserver.rb +12 -59
  182. data/lib/spiderfw/config/configuration.rb +4 -0
  183. data/lib/spiderfw/config/options/spider.rb +25 -8
  184. data/lib/spiderfw/controller/controller.rb +10 -4
  185. data/lib/spiderfw/controller/first_responder.rb +6 -20
  186. data/lib/spiderfw/controller/http_controller.rb +2 -1
  187. data/lib/spiderfw/controller/mixins/http_mixin.rb +12 -1
  188. data/lib/spiderfw/controller/mixins/visual.rb +3 -16
  189. data/lib/spiderfw/env.rb +1 -1
  190. data/lib/spiderfw/http/server.rb +178 -2
  191. data/lib/spiderfw/model/base_model.rb +142 -111
  192. data/lib/spiderfw/model/data_type.rb +15 -0
  193. data/lib/spiderfw/model/datatypes/decimal.rb +8 -0
  194. data/lib/spiderfw/model/datatypes/pk.rb +29 -0
  195. data/lib/spiderfw/model/datatypes.rb +1 -0
  196. data/lib/spiderfw/model/element.rb +5 -1
  197. data/lib/spiderfw/model/extended_models/managed.rb +1 -1
  198. data/lib/spiderfw/model/junction.rb +23 -0
  199. data/lib/spiderfw/model/mappers/db_mapper.rb +96 -80
  200. data/lib/spiderfw/model/mappers/document_mapper.rb +315 -0
  201. data/lib/spiderfw/model/mappers/mapper.rb +164 -75
  202. data/lib/spiderfw/model/mixins/list.rb +1 -0
  203. data/lib/spiderfw/model/mixins/versioned.rb +63 -27
  204. data/lib/spiderfw/model/model.rb +36 -9
  205. data/lib/spiderfw/model/query_funcs.rb +3 -0
  206. data/lib/spiderfw/model/query_set.rb +21 -1
  207. data/lib/spiderfw/model/storage/base_storage.rb +259 -6
  208. data/lib/spiderfw/model/storage/{db/db_connection_pool.rb → connection_pool.rb} +25 -21
  209. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +25 -5
  210. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
  211. data/lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb +2 -2
  212. data/lib/spiderfw/model/storage/db/connectors/oci8.rb +3 -4
  213. data/lib/spiderfw/model/storage/db/db_storage.rb +18 -219
  214. data/lib/spiderfw/model/storage/document/adapters/mongodb.rb +307 -0
  215. data/lib/spiderfw/model/storage/document/document.rb +7 -0
  216. data/lib/spiderfw/model/storage/document/document_storage.rb +34 -0
  217. data/lib/spiderfw/model/storage.rb +23 -11
  218. data/lib/spiderfw/model/unit_of_work.rb +45 -22
  219. data/lib/spiderfw/spider.rb +660 -0
  220. data/lib/spiderfw/templates/blocks/html.rb +4 -2
  221. data/lib/spiderfw/templates/blocks/run.rb +1 -1
  222. data/lib/spiderfw/templates/blocks/tag_if.rb +1 -1
  223. data/lib/spiderfw/templates/blocks/widget.rb +1 -1
  224. data/lib/spiderfw/templates/layout.rb +29 -5
  225. data/lib/spiderfw/templates/template.rb +72 -7
  226. data/lib/spiderfw/templates/template_blocks.rb +1 -1
  227. data/lib/spiderfw/test/capybara.rb +7 -0
  228. data/lib/spiderfw/test/cucumber.rb +12 -0
  229. data/lib/spiderfw/test/page_object.rb +29 -0
  230. data/lib/spiderfw/test/spec.rb +20 -0
  231. data/lib/spiderfw/test/stubs/mapper_stub.rb +18 -0
  232. data/lib/spiderfw/test/stubs/storage_stub.rb +23 -0
  233. data/lib/spiderfw/test/unit.rb +23 -0
  234. data/lib/spiderfw/test.rb +89 -0
  235. data/lib/spiderfw/utils/json.rb +6 -0
  236. data/lib/spiderfw/utils/logger.rb +17 -4
  237. data/lib/spiderfw/utils/loggers/apache_commons_logger.rb +61 -0
  238. data/lib/spiderfw/utils/monkey/date_time.rb +2 -2
  239. data/lib/spiderfw/utils/monkey/module.rb +3 -1
  240. data/lib/spiderfw/utils/profiling.rb +2 -2
  241. data/lib/spiderfw/widget/widget.rb +31 -13
  242. data/lib/spiderfw.rb +1 -597
  243. data/spider.gemspec +9 -10
  244. metadata +193 -132
  245. data/apps/admin/_init.rb +0 -9
  246. data/apps/admin/controllers/admin_controller.rb +0 -12
  247. data/apps/admin/widgets/dashboard_widget/dashboard_widget.rb +0 -8
  248. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/AUTHORS.txt +0 -30
  249. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery-ui-i18n.js +0 -1176
  250. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/ui/i18n/jquery.ui.datepicker-no.js +0 -23
  251. data/apps/core/components/public/js/jquery/jquery-ui-1.8.4/development-bundle/version.txt +0 -1
  252. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.css +0 -64
  253. data/apps/core/components/public/js/jquery/plugins/asmselect/jquery.asmselect.js +0 -407
  254. data/apps/core/components/widgets/switcher/switcher.shtml +0 -17
  255. data/apps/master/po/master.pot +0 -400
@@ -0,0 +1,660 @@
1
+ require 'spiderfw/env'
2
+
3
+ require 'rubygems'
4
+ require 'find'
5
+ require 'fileutils'
6
+ require 'pathname'
7
+ require 'bundler/setup'
8
+ require 'spiderfw/autoload'
9
+ require 'spiderfw/requires'
10
+
11
+ require 'spiderfw/version'
12
+
13
+
14
+ module Spider
15
+
16
+ @apps = {}; @apps_by_path = {}; @apps_by_short_name = {}; @loaded_apps = {}
17
+ @paths = {}
18
+ @resource_types = {}
19
+ @spawner = nil
20
+
21
+ class << self
22
+ # Everything here must be thread safe!!!
23
+
24
+ # An instance of the shared logger.
25
+ attr_reader :logger
26
+ # An hash of registered Spider::App, indexed by name.
27
+ attr_reader :apps
28
+ # An hash of registred Spider::App modules, indexed by path.
29
+ attr_reader :apps_by_path
30
+ # An hash of registred Spider::App modules, indexed by short name (name without namespace).
31
+ attr_reader :apps_by_short_name
32
+ # The current runmode (test, devel or production).
33
+ attr_reader :runmode
34
+ # An hash of runtime paths.
35
+ # :root:: The base runtime path.
36
+ # :apps:: Apps folder.
37
+ # :core_apps:: Spider apps folder.
38
+ # :config:: Config folder.
39
+ # :views:: Runtime views folder.
40
+ # :var:: Var folder. Must be writable. Contains cache, logs, and other files written by the server.
41
+ # :data:: Data folder. Holds static and dynamic files. Some subdirs may have to be writable.
42
+ # :certs:: Certificates folder.
43
+ # ::tmp:: Temp folder. Must be writable.
44
+ # ::log:: Log location.
45
+ attr_reader :paths
46
+ # Current Home
47
+ attr_reader :home
48
+ # Registered resource types
49
+ attr_reader :resource_types
50
+ # Main site
51
+ attr_accessor :site
52
+ attr_accessor :spawner
53
+
54
+ # Initializes the runtime environment. This method is called when spider is required. Apps may implement
55
+ # an app_init method, that will be called after Spider::init is done.
56
+ def init(force=false)
57
+ return if @init_done && !force
58
+
59
+ init_base(force)
60
+
61
+ start_loggers
62
+
63
+ # @controller = Controller
64
+ @paths[:spider] = $SPIDER_PATH
65
+
66
+ if ($SPIDER_CONFIG_SETS)
67
+ $SPIDER_CONFIG_SETS.each{ |set| @configuration.include_set(set) }
68
+ end
69
+ init_file = File.join($SPIDER_RUN_PATH, 'init.rb')
70
+ if File.exist?(init_file)
71
+ @home.instance_eval(File.read(init_file), init_file)
72
+ end
73
+
74
+ @apps.each do |name, mod|
75
+ mod.app_init if mod.respond_to?(:app_init)
76
+ end
77
+ GetText::LocalePath.memoize_clear # since new paths have been added to GetText
78
+ @apps.each do |name, mod|
79
+ if File.directory?(File.join(mod.path, 'po'))
80
+ GetText.bindtextdomain(mod.short_name)
81
+ end
82
+ end
83
+ @init_done=true
84
+ end
85
+
86
+ def init_done?
87
+ @init_done
88
+ end
89
+
90
+ def init_base(force=false)
91
+ return if @init_base_done && !force
92
+
93
+ @apps_to_load = []
94
+ @root = $SPIDER_RUN_PATH
95
+ @home = Home.new(@root)
96
+
97
+ require 'spiderfw/config/options/spider.rb'
98
+
99
+ setup_paths(@root)
100
+ all_apps = find_all_apps
101
+ all_apps.each do |path|
102
+ load_configuration(File.join(path, 'config'))
103
+ end
104
+ @runmode = nil
105
+ self.runmode = $SPIDER_RUNMODE if $SPIDER_RUNMODE
106
+
107
+ load_configuration File.join($SPIDER_PATH, 'config')
108
+ load_configuration File.join(@root, 'config')
109
+ Locale.default = Spider.conf.get('i18n.default_locale')
110
+ @init_base_done = true
111
+ end
112
+
113
+ #
114
+ # def stop
115
+ # @apps.each do |name, mod|
116
+ # mod.app_stop if mod.respond_to?(:app_stop)
117
+ # end
118
+ # end
119
+
120
+
121
+ # Invoked before a server is started. Apps may implement the app_startup method, that will be called.
122
+ def startup
123
+ unless File.exists?(File.join(Spider.paths[:root], 'init.rb'))
124
+ raise "The server must be started from the root directory"
125
+ end
126
+ FileUtils.mkdir_p(Spider.paths[:tmp])
127
+ FileUtils.mkdir_p(Spider.paths[:var])
128
+ if Spider.conf.get('template.cache.reload_on_restart')
129
+ FileUtils.touch("#{Spider.paths[:tmp]}/templates_reload.txt")
130
+ end
131
+ unless Spider.runmode == 'test'
132
+ if domain = Spider.conf.get('site.domain')
133
+ ssl_port = Spider.conf.get('site.ssl') ? Spider.conf.get('site.ssl_port') : nil
134
+ Spider.site = Site.new(domain, Spider.conf.get('site.port'), ssl_port)
135
+ elsif File.exists?(Site.cache_file)
136
+ Spider.site = Site.load_cache
137
+ end
138
+ end
139
+ if Spider.conf.get('request.mutex')
140
+ mutex_requests!
141
+ end
142
+ @apps.each do |name, mod|
143
+ mod.app_startup if mod.respond_to?(:app_startup)
144
+ end
145
+
146
+ @startup_done = true
147
+ end
148
+
149
+ def startup_done?
150
+ @startup_done
151
+ end
152
+
153
+ # Invoked when a server is shutdown. Apps may implement the app_shutdown method, that will be called.
154
+ def shutdown
155
+ return unless Thread.current == Thread.main
156
+ Debugger.post_mortem = false if Object.const_defined?(:Debugger) && Debugger.post_mortem?
157
+ @apps.each do |name, mod|
158
+ mod.app_shutdown if mod.respond_to?(:app_shutdown)
159
+ end
160
+ end
161
+
162
+ def current
163
+ Spider::Request.current
164
+ end
165
+
166
+ def request_started
167
+ @request_mutex.lock if (@request_mutex)
168
+ Spider::Request.current = {
169
+ :_start => Time.now
170
+ }
171
+ end
172
+
173
+ def request_finished
174
+ # Spider.logger.info("Done in #{(Time.now - Spider::Request.current[:_start])*1000}ms")
175
+ Spider::Request.reset_current
176
+ @request_mutex.unlock if (@request_mutex)
177
+ end
178
+
179
+ def mutex_requests!
180
+ @request_mutex = Mutex.new
181
+ end
182
+
183
+ def request_mutex
184
+ @request_mutex
185
+ end
186
+
187
+ def request_mutex=(val)
188
+ @request_mutex = val
189
+ end
190
+
191
+
192
+ # Closes any open loggers, and opens new ones based on configured settings.
193
+ def start_loggers(force=false)
194
+ return if @logger && !force
195
+ @logger ||= Spider::Logger
196
+ @logger.close_all
197
+ @logger.open(STDERR, Spider.conf.get('log.console')) if Spider.conf.get('log.console')
198
+ begin
199
+ FileUtils.mkdir(@paths[:log]) unless File.exist?(@paths[:log])
200
+ rescue => exc
201
+ @logger.error("Unable to create log folder") if File.exist?(File.dirname(@paths[:log]))
202
+ end
203
+ if @paths[:log] && File.exist?(@paths[:log])
204
+ @logger.open(File.join(@paths[:log], 'error.log'), :ERROR) if Spider.conf.get('log.errors')
205
+ if Spider.conf.get('log.level')
206
+ @logger.open(File.join(@paths[:log], Spider.conf.get('log.file_name')), Spider.conf.get('log.level'))
207
+ end
208
+ end
209
+ if RUBY_PLATFORM =~ /java/ && Spider.conf.get('log.apache_commons')
210
+ begin
211
+ require 'spiderfw/utils/loggers/apache_commons_logger'
212
+ l = Spider::Loggers::ApacheCommonsLogger.new
213
+ @logger.add('apache_commons_logger', l)
214
+ rescue NameError
215
+ $stderr << "Warning: Unable to load Java class org.apache.commons.logging.LogFactory\n"
216
+ end
217
+ end
218
+ $LOG = @logger
219
+ Object.const_set(:LOGGER, @logger)
220
+ end
221
+
222
+ def start_loggers!
223
+ start_loggers(false)
224
+ end
225
+
226
+ # Sets the default paths (see #paths).
227
+ def setup_paths(root)
228
+ @paths[:root] = root
229
+ @paths[:apps] = File.join(root, 'apps')
230
+ @paths[:core_apps] = File.join($SPIDER_PATH, 'apps')
231
+ @paths[:config] = File.join(root, 'config')
232
+ @paths[:layouts] = File.join(root, 'layouts')
233
+ @paths[:var] = File.join(root, 'var')
234
+ @paths[:certs] = File.join(@paths[:config], 'certs')
235
+ @paths[:tmp] = File.join(root, 'tmp')
236
+ @paths[:data] = File.join(root, 'data')
237
+ @paths[:log] = File.join(@paths[:var], 'log')
238
+ end
239
+
240
+ # Finds an app by name, looking in paths[:apps] and paths[:core_apps]. Returns the found path.
241
+ def find_app(name)
242
+ path = nil
243
+ [@paths[:apps], @paths[:core_apps]].each do |base|
244
+ test = File.join(base, name)
245
+ if File.exist?(File.join(test, '_init.rb'))
246
+ path = test
247
+ break
248
+ end
249
+ end
250
+ return path
251
+ end
252
+
253
+ def find_apps(name)
254
+ [@paths[:apps], @paths[:core_apps]].each do |base|
255
+ test = File.join(base, name)
256
+ if File.exist?(test)
257
+ return find_apps_in_folder(test)
258
+ end
259
+ end
260
+ end
261
+
262
+ def load_app(name)
263
+ paths = find_apps(name)
264
+ paths.each do |path|
265
+ load_app_at_path(path)
266
+ end
267
+ end
268
+
269
+ def load_app_at_path(path)
270
+ return if @loaded_apps[path]
271
+ relative_path = path
272
+ if path.index(Spider.paths[:root])
273
+ home = Pathname.new(Spider.paths[:root])
274
+ pname = Pathname.new(path)
275
+ relative_path = pname.relative_path_from(home).to_s
276
+ end
277
+ @loaded_apps[path] = true
278
+ last_name = File.basename(path)
279
+ app_files = ['_init.rb', last_name+'.rb', 'cmd.rb']
280
+ app_files.each{ |f| require File.join(relative_path, f) if File.exist?(File.join(path, f)) }
281
+ GetText::LocalePath.add_default_rule(File.join(path, "data/locale/%{lang}/LC_MESSAGES/%{name}.mo"))
282
+ end
283
+
284
+ def load_apps(*l)
285
+ l.each do |app|
286
+ load_app(app)
287
+ end
288
+ end
289
+
290
+ def load_all_apps
291
+ find_all_apps.each do |path|
292
+ load_app_at_path(path)
293
+ end
294
+ end
295
+
296
+ def find_all_apps
297
+ app_paths = []
298
+ Find.find(@paths[:core_apps], @paths[:apps]) do |path|
299
+ if (File.basename(path) == '_init.rb')
300
+ app_paths << File.dirname(path)
301
+ Find.prune
302
+ elsif File.exist?(File.join(path, '_init.rb'))
303
+ app_paths << path
304
+ Find.prune
305
+ end
306
+ end
307
+ return app_paths
308
+ end
309
+
310
+ def find_apps_in_folder(path)
311
+ return unless File.directory?(path)
312
+ return [path] if File.exist?(File.join(path, '_init.rb'))
313
+ found = []
314
+ Dir.new(path).each do |f|
315
+ next if f[0].chr == '.'
316
+ found_path = File.join(path, f)
317
+ if File.exist?(File.join(found_path, '/_init.rb'))
318
+ found << found_path
319
+ else
320
+ found += find_apps_in_folder(found_path)
321
+ end
322
+ end
323
+ return found
324
+ end
325
+
326
+ def add_app(mod)
327
+ @apps[mod.name] = mod
328
+ @apps_by_path[mod.relative_path] = mod
329
+ @apps_by_short_name[mod.short_name] = mod
330
+ end
331
+
332
+ def app?(path_or_name)
333
+ return true if @apps_by_path[path_or_name]
334
+ return true if @apps_by_short_name[path_or_name]
335
+ return false
336
+ end
337
+
338
+ def load_configuration(path)
339
+ return unless File.directory?(path)
340
+ opts = File.join(path, 'options.rb')
341
+ require opts if File.exist?(opts)
342
+ Dir.new(path).each do |f|
343
+ f.untaint # FIXME: security parse
344
+ case f
345
+ when /^\./
346
+ next
347
+ when /\.(yaml|yml)$/
348
+ begin
349
+ @configuration.load_yaml(File.join(path, f))
350
+ rescue ConfigurationException => exc
351
+ if (exc.type == :yaml)
352
+ err = "Configuration file #{path+f} is not valid YAML"
353
+ if @logger
354
+ @logger.error(err)
355
+ else
356
+ puts err
357
+ end
358
+ else
359
+ raise
360
+ end
361
+ end
362
+ end
363
+ end
364
+ end
365
+
366
+ # Returns the default controller.
367
+ def controller
368
+ require 'spiderfw/controller/spider_controller'
369
+ SpiderController
370
+ end
371
+
372
+ # Sets routes on the #controller for the given apps.
373
+ def route_apps(*apps)
374
+ options = {}
375
+ if apps[-1].is_a?(Hash)
376
+ options = apps.pop
377
+ end
378
+ @route_apps = apps.empty? ? true : apps
379
+ if (@route_apps)
380
+ apps_to_route = @route_apps == true ? self.apps.values : @route_apps.map{ |name| self.apps[name] }
381
+ end
382
+ if options[:except]
383
+ apps_to_route.reject{ |app| options[:except].include?(app) }
384
+ end
385
+ if (apps_to_route)
386
+ apps_to_route.each{ |app| @home.controller.route_app(app) }
387
+ end
388
+ end
389
+
390
+ # Adds a resource type
391
+ # name must be a symbol, extensions an array of extensions (strings, without the dot) for this resource.
392
+ # Options may be:
393
+ # :extensions an array of possible extensions. If given, find_resource will try appending the extensions
394
+ # when looking for the file.
395
+ # :path the path of the resource relative to resource root; if not given, name will be used.
396
+ #
397
+ def register_resource_type(name, options={})
398
+ @resource_types[name] = {
399
+ :extensions => options[:extensions],
400
+ :path => options[:path] || name.to_s
401
+ }
402
+ end
403
+
404
+ Spider.register_resource_type(:views, :extensions => ['shtml'])
405
+
406
+ def path
407
+ $SPIDER_PATH
408
+ end
409
+
410
+ def relative_path
411
+ '/spider'
412
+ end
413
+
414
+ # Returns the full path of a resource.
415
+ # resource_type may be :views, or any other type registered with #register_resource_type
416
+ # path is the path of the resource, relative to the resource folder
417
+ # cur_path, if provided, is the current working path
418
+ # owner_class, if provided, must respond to *app*
419
+ #
420
+ # Will look for the resource in the runtime root first, than in the
421
+ # app's :"#{resource_type}_path", and finally in the spider folder.
422
+ def find_resource(resource_type, path, cur_path=nil, owner_classes=nil, search_paths=[])
423
+ owner_classes = [owner_classes] unless owner_classes.is_a?(Enumerable)
424
+ # FIXME: security check for allowed paths?
425
+ def first_found(extensions, path)
426
+ extensions.each do |ext|
427
+ full = path
428
+ full += '.'+ext if ext
429
+ return full if (File.exist?(full))
430
+ end
431
+ return nil
432
+ end
433
+
434
+ search_paths ||= []
435
+ owner_classes.each do |owner_class| # FIXME: refactor
436
+ next if owner_class.is_a?(Spider::Home) # home is already checked for other owner_classes
437
+ # FIXME: maybe it shouldn't get here?
438
+ owner_class = nil if owner_class == NilClass
439
+ resource_config = @resource_types[resource_type]
440
+ raise "Unknown resource type #{resource_type}" unless resource_config
441
+ resource_rel_path = resource_config[:path]
442
+ extensions = [nil] + resource_config[:extensions]
443
+ path.strip!
444
+ if (path[0..3] == 'ROOT')
445
+ path.sub!(/^ROOT/, Spider.paths[:root])
446
+ return Resource.new(path, @home)
447
+ elsif (path[0..5] == 'SPIDER')
448
+ path.sub!(/^SPIDER/, $SPIDER_PATH)
449
+ return Resource.new(path, self)
450
+ elsif (cur_path)
451
+ if (path[0..1] == './')
452
+ return Resource.new(first_found(extensions, cur_path+path[1..-1]), owner_class)
453
+ elsif (path[0..1] == '../')
454
+ return Resource.new(first_found(extensions, File.dirname(cur_path)+path[2..-1]), owner_class)
455
+ end
456
+ end
457
+ app = nil
458
+ path_app = nil
459
+ if (path[0].chr == '/')
460
+ first_part = path[1..-1].split('/')[0]
461
+ Spider.apps_by_path.each do |p, a|
462
+ if path.index(p+'/') == 1 # FIXME: might not be correct
463
+ #if first_part == p
464
+ path_app = a
465
+ path = path[p.length+2..-1]
466
+ break
467
+ end
468
+ end
469
+ app = path_app
470
+ elsif owner_class <= Spider::App
471
+ app = owner_class
472
+ else
473
+ app = owner_class.app if (owner_class && owner_class.app)
474
+ end
475
+ return Resource.new(cur_path+'/'+path, owner_class) if cur_path && File.exist?(cur_path+'/'+path) # !app
476
+ raise "Can't find owner app for resource #{path}" unless app
477
+ search_locations = resource_search_locations(resource_type, app)
478
+ search_paths.each do |p|
479
+ p = [p, owner_class] unless p.is_a?(Array)
480
+ search_locations << p
481
+ end
482
+ search_locations.each do |p|
483
+ found = first_found(extensions, p[0]+'/'+path)
484
+ next if found == cur_path
485
+ definer = path_app || p[1]
486
+ return Resource.new(found, definer) if found
487
+ end
488
+ end
489
+ return Resource.new(path)
490
+ end
491
+
492
+ def resource_search_locations(resource_type, app=nil)
493
+ resource_config = @resource_types[resource_type]
494
+ resource_rel_path = resource_config[:path]
495
+ app_rel_path = app && app.respond_to?(:relative_path) ? app.relative_path : nil
496
+ search_locations = []
497
+ unless Spider.conf.get('resources.disable_custom')
498
+ root_search = File.join(Spider.paths[:root], resource_rel_path)
499
+ root_search = File.join(root_search, app_rel_path) if app_rel_path
500
+ # unless cur_path && cur_path == File.join(root_search, path)
501
+ search_locations = [[root_search, @home]]
502
+ # end
503
+ end
504
+ if app
505
+ if app.respond_to?("#{resource_type}_path")
506
+ search_locations << [app.send("#{resource_type}_path"), app]
507
+ else
508
+ search_locations << [File.join(app.path, resource_rel_path), app]
509
+ end
510
+ if Spider.runmode == 'test'
511
+ search_locations << [File.join(app.path, 'test', resource_rel_path), app]
512
+ end
513
+ end
514
+ spider_path = File.join($SPIDER_PATH, resource_rel_path)
515
+ search_locations << [spider_path, self]
516
+ search_locations
517
+ end
518
+
519
+ def list_resources(resource_type, owner_class=nil, start=nil, search_paths = [])
520
+ app = nil
521
+ if owner_class <= Spider::App
522
+ app = owner_class
523
+ else
524
+ app = owner_class.app if (owner_class && owner_class.app)
525
+ end
526
+ search_locations = resource_search_locations(resource_type, app)
527
+ resource_config = @resource_types[resource_type]
528
+ extensions = resource_config[:extensions]
529
+ search_paths.each do |p|
530
+ p = [p, owner_class] unless p.is_a?(Array)
531
+ search_locations << p
532
+ end
533
+ res = []
534
+ search_locations.reverse.each do |p|
535
+ pname = Pathname.new(p[0])
536
+ base = p[0]
537
+ base = File.join(base, start) if start
538
+ extensions.each do |ext|
539
+ Dir.glob(File.join(base, "*.#{ext}")).each do |f|
540
+ res << (Pathname.new(f).relative_path_from(pname)).to_s
541
+ end
542
+ end
543
+ end
544
+ res.uniq
545
+
546
+ end
547
+
548
+ def find_resource_path(resource_type, path, cur_path=nil, owner_classes=nil, search_paths=[])
549
+ res = find_resource(resource_type, path, cur_path, owner_classes, search_paths)
550
+ return res ? res.path : nil
551
+ end
552
+
553
+
554
+ # Source file management
555
+
556
+ def sources_in_dir(path)
557
+ loaded = []
558
+ $".each do |file|
559
+ basename = File.basename(file)
560
+ next if (basename == 'spider.rb' || basename == 'options.rb')
561
+ if (file[0..path.length-1] == path)
562
+ loaded.push(file)
563
+ else
564
+ $:.each do |dir|
565
+ file_path = File.join(dir, file)
566
+ if (file_path =~ /^#{path}/) # FileTest.exists?(file_path) &&
567
+ loaded.push(file_path)
568
+ end
569
+ end
570
+ end
571
+ end
572
+ return loaded
573
+ end
574
+
575
+ def reload_sources_in_dir(dir)
576
+ self.sources_in_dir(dir).each do |file|
577
+ load(file)
578
+ end
579
+ end
580
+
581
+ def reload_sources
582
+ logger.debug("Reloading sources")
583
+ crit = Thread.critical
584
+ Thread.critical = true
585
+ $".each do |file|
586
+ if file =~ /^(#{$SPIDER_RUN_PATH}|apps)/
587
+ # logger.debug("RELOADING #{file}")
588
+ load(file)
589
+ else
590
+ # logger.debug("SKIPPING #{file}")
591
+ end
592
+ end
593
+ Thread.critical = crit
594
+ end
595
+
596
+ def respawn!
597
+ # TODO
598
+ raise "Unimplemented"
599
+ Spider.logger.info("Respawning")
600
+ @spawner.write('spawn')
601
+ @spawner.close
602
+ Process.kill "KILL", Process.pid
603
+ end
604
+
605
+ def runmode=(mode)
606
+ raise "Can't change runmode" if @runmode
607
+ @runmode = mode
608
+ @configuration.include_set(mode)
609
+ if Spider.conf.get('debugger.start') || File.exists?(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
610
+ init_debug
611
+ end
612
+ if (mode != 'production')
613
+ Spider.paths[:var] = File.join(Spider.paths[:var], mode)
614
+ end
615
+ end
616
+
617
+ def init_debug
618
+ begin
619
+ require 'ruby-debug'
620
+ if File.exists?(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
621
+ Debugger.wait_connection = true
622
+ Debugger.start_remote
623
+ File.delete(File.join($SPIDER_RUN_PATH,'tmp', 'debug.txt'))
624
+ else
625
+ Debugger.start
626
+ end
627
+ rescue LoadError, RuntimeError => exc
628
+ Spider.logger.warn(exc.message)
629
+ end
630
+ end
631
+
632
+ def locale
633
+ Locale.current[0]
634
+ end
635
+
636
+ def i18n(l = self.locale)
637
+ Spider::I18n.provider(l)
638
+ end
639
+
640
+ def test_setup
641
+ end
642
+
643
+ def test_teardown
644
+ end
645
+
646
+ def _test_setup
647
+ @apps.each do |name, mod|
648
+ mod.test_setup if mod.respond_to?(:test_setup)
649
+ end
650
+ end
651
+
652
+ def _test_teardown
653
+ @apps.each do |name, mod|
654
+ mod.test_teardown if mod.respond_to?(:test_teardown)
655
+ end
656
+ end
657
+
658
+ end
659
+
660
+ end
@@ -3,6 +3,7 @@ require 'spiderfw/templates/template_blocks'
3
3
  module Spider; module TemplateBlocks
4
4
 
5
5
  class HTML < Block
6
+ HTML_NO_CLOSE = ['br', 'img']
6
7
 
7
8
  def compile(options={})
8
9
  c = ""
@@ -18,7 +19,7 @@ module Spider; module TemplateBlocks
18
19
  c += "unless self[:widget][:target_only] && !self[:widget][:is_target]\n" if (options[:mode] == :widget && is_root)
19
20
  c, init = compile_content(c, init, options)
20
21
  c += "end\n" if (options[:mode] == :widget && is_root)
21
- end_tag = get_end
22
+ end_tag = get_end(options)
22
23
  c += "$out << '#{end_tag}'\n" if end_tag
23
24
  return CompiledBlock.new(init, c)
24
25
  end
@@ -55,7 +56,8 @@ module Spider; module TemplateBlocks
55
56
  return start
56
57
  end
57
58
 
58
- def get_end
59
+ def get_end(options)
60
+ return nil if options[:doctype].html? && HTML_NO_CLOSE.include?(@el.name.downcase)
59
61
  str = escape_text(@el.etag.inspect) if @el.etag
60
62
  str = str[1..-2] if str && str[0].chr == '"' # FIXME: This is a workaround Hpricot 0.6 and 0.8 differences
61
63
  return str
@@ -51,7 +51,7 @@ module Spider; module TemplateBlocks
51
51
  attr_name = at.get_attribute('name').gsub("'", "\\\\'")
52
52
  attr_value = at.get_attribute('value').gsub("'", "\\\\'")
53
53
 
54
- init += "@owner.widget_attributes[#{widget_id}][:#{attr_name}] = '#{attr_value}'\n"
54
+ init += "@owner.widget_attributes[#{widget_id}][:\"#{attr_name}\"] = '#{attr_value}'\n"
55
55
  end
56
56
  end
57
57
  @el.innerHTML = ''