olelo 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. data/.gitignore +10 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +3 -0
  4. data/README.markdown +104 -0
  5. data/Rakefile +92 -0
  6. data/bin/olelo +5 -0
  7. data/config.ru +86 -0
  8. data/config/aspects.rb +256 -0
  9. data/config/config.yml.default +154 -0
  10. data/config/initializers/00-mime_types.rb +29 -0
  11. data/config/initializers/01-slim.rb +2 -0
  12. data/config/interwiki.yml +11 -0
  13. data/doc/AUTHORS +7 -0
  14. data/doc/LICENSE +22 -0
  15. data/lib/olelo.rb +39 -0
  16. data/lib/olelo/application.rb +294 -0
  17. data/lib/olelo/attributes.rb +285 -0
  18. data/lib/olelo/config.rb +88 -0
  19. data/lib/olelo/extensions.rb +252 -0
  20. data/lib/olelo/helper.rb +290 -0
  21. data/lib/olelo/hooks.rb +142 -0
  22. data/lib/olelo/html_safe.rb +29 -0
  23. data/lib/olelo/initializer.rb +76 -0
  24. data/lib/olelo/locale.rb +63 -0
  25. data/lib/olelo/locale.yml +284 -0
  26. data/lib/olelo/menu.rb +101 -0
  27. data/lib/olelo/middleware/blacklist.rb +25 -0
  28. data/lib/olelo/middleware/degrade_mime_type.rb +19 -0
  29. data/lib/olelo/middleware/flash.rb +97 -0
  30. data/lib/olelo/middleware/force_encoding.rb +41 -0
  31. data/lib/olelo/page.rb +266 -0
  32. data/lib/olelo/patch.rb +311 -0
  33. data/lib/olelo/plugin.rb +188 -0
  34. data/lib/olelo/repository.rb +225 -0
  35. data/lib/olelo/routing.rb +223 -0
  36. data/lib/olelo/templates.rb +30 -0
  37. data/lib/olelo/user.rb +132 -0
  38. data/lib/olelo/util.rb +233 -0
  39. data/lib/olelo/version.rb +3 -0
  40. data/lib/olelo/virtualfs.rb +161 -0
  41. data/lib/rack/olelo_patches.rb +33 -0
  42. data/lib/rack/relative_redirect.rb +44 -0
  43. data/lib/rack/static_cache.rb +93 -0
  44. data/lib/yard/addons.rb +1 -0
  45. data/lib/yard/addons/hook_handler.rb +25 -0
  46. data/lib/yard/addons/override_tag.rb +14 -0
  47. data/lib/yard/addons/route_handler.rb +33 -0
  48. data/lib/yard/addons/sanitize_anchor.rb +16 -0
  49. data/olelo.gemspec +31 -0
  50. data/plugins/aspects/changelog.rb +45 -0
  51. data/plugins/aspects/documentbrowser.rb +57 -0
  52. data/plugins/aspects/download.rb +11 -0
  53. data/plugins/aspects/highlight.rb +8 -0
  54. data/plugins/aspects/image.rb +41 -0
  55. data/plugins/aspects/imageinfo.rb +64 -0
  56. data/plugins/aspects/locale.yml +60 -0
  57. data/plugins/aspects/main.rb +199 -0
  58. data/plugins/aspects/pageinfo.rb +37 -0
  59. data/plugins/aspects/source.rb +6 -0
  60. data/plugins/aspects/subpages.rb +44 -0
  61. data/plugins/aspects/text.rb +9 -0
  62. data/plugins/blog/blog.css +1 -0
  63. data/plugins/blog/blog.scss +37 -0
  64. data/plugins/blog/locale.yml +12 -0
  65. data/plugins/blog/main.rb +85 -0
  66. data/plugins/editor/locale.yml +18 -0
  67. data/plugins/editor/markup/main.rb +3 -0
  68. data/plugins/editor/markup/script.js +10 -0
  69. data/plugins/editor/markup/script/00-jquery.textselection.js +267 -0
  70. data/plugins/editor/markup/script/01-olelo.markupeditor.js +116 -0
  71. data/plugins/editor/markup/script/init.js +10 -0
  72. data/plugins/editor/preview.rb +52 -0
  73. data/plugins/editor/recaptcha.rb +56 -0
  74. data/plugins/filters/creole.rb +37 -0
  75. data/plugins/filters/disposition.rb +9 -0
  76. data/plugins/filters/editsection.rb +67 -0
  77. data/plugins/filters/fix_img_tag.rb +16 -0
  78. data/plugins/filters/html_wrapper.rb +12 -0
  79. data/plugins/filters/interwiki.rb +19 -0
  80. data/plugins/filters/link_classifier.rb +26 -0
  81. data/plugins/filters/locale.yml +15 -0
  82. data/plugins/filters/main.rb +202 -0
  83. data/plugins/filters/markdown_nowiki.rb +15 -0
  84. data/plugins/filters/numbering.xsl +93 -0
  85. data/plugins/filters/orgmode.rb +6 -0
  86. data/plugins/filters/rubypants.rb +6 -0
  87. data/plugins/filters/s5/main.rb +32 -0
  88. data/plugins/filters/s5/s5.xsl +118 -0
  89. data/plugins/filters/tilt.rb +17 -0
  90. data/plugins/filters/toc.rb +50 -0
  91. data/plugins/filters/xhtml2latex.xsl +232 -0
  92. data/plugins/filters/xslt.rb +22 -0
  93. data/plugins/gallery/gallery.css +1 -0
  94. data/plugins/gallery/gallery.scss +28 -0
  95. data/plugins/gallery/main.rb +34 -0
  96. data/plugins/misc/fancybox/images/blank.gif +0 -0
  97. data/plugins/misc/fancybox/images/fancy_close.png +0 -0
  98. data/plugins/misc/fancybox/images/fancy_loading.png +0 -0
  99. data/plugins/misc/fancybox/images/fancy_nav_left.png +0 -0
  100. data/plugins/misc/fancybox/images/fancy_nav_right.png +0 -0
  101. data/plugins/misc/fancybox/images/fancy_shadow_e.png +0 -0
  102. data/plugins/misc/fancybox/images/fancy_shadow_n.png +0 -0
  103. data/plugins/misc/fancybox/images/fancy_shadow_ne.png +0 -0
  104. data/plugins/misc/fancybox/images/fancy_shadow_nw.png +0 -0
  105. data/plugins/misc/fancybox/images/fancy_shadow_s.png +0 -0
  106. data/plugins/misc/fancybox/images/fancy_shadow_se.png +0 -0
  107. data/plugins/misc/fancybox/images/fancy_shadow_sw.png +0 -0
  108. data/plugins/misc/fancybox/images/fancy_shadow_w.png +0 -0
  109. data/plugins/misc/fancybox/images/fancy_title_left.png +0 -0
  110. data/plugins/misc/fancybox/images/fancy_title_main.png +0 -0
  111. data/plugins/misc/fancybox/images/fancy_title_over.png +0 -0
  112. data/plugins/misc/fancybox/images/fancy_title_right.png +0 -0
  113. data/plugins/misc/fancybox/images/fancybox-x.png +0 -0
  114. data/plugins/misc/fancybox/images/fancybox-y.png +0 -0
  115. data/plugins/misc/fancybox/images/fancybox.png +0 -0
  116. data/plugins/misc/fancybox/jquery.fancybox.css +1 -0
  117. data/plugins/misc/fancybox/jquery.fancybox.scss +323 -0
  118. data/plugins/misc/fancybox/main.rb +4 -0
  119. data/plugins/misc/fancybox/script.js +37 -0
  120. data/plugins/misc/fancybox/script/00-jquery.mousewheel.js +84 -0
  121. data/plugins/misc/fancybox/script/01-jquery.easing.js +205 -0
  122. data/plugins/misc/fancybox/script/02-jquery.fancybox.js +1156 -0
  123. data/plugins/misc/fancybox/script/init.js +18 -0
  124. data/plugins/misc/system.rb +192 -0
  125. data/plugins/misc/variables.rb +29 -0
  126. data/plugins/misc/webdav.rb +45 -0
  127. data/plugins/repositories/git_grep.rb +69 -0
  128. data/plugins/repositories/gitrb_repository.rb +204 -0
  129. data/plugins/repositories/locale.yml +12 -0
  130. data/plugins/repositories/rugged_repository.rb +454 -0
  131. data/plugins/security/acl.rb +57 -0
  132. data/plugins/security/basic_auth.rb +21 -0
  133. data/plugins/security/locale.yml +21 -0
  134. data/plugins/security/persistent_login.rb +32 -0
  135. data/plugins/security/portal.rb +28 -0
  136. data/plugins/security/private_wiki.rb +24 -0
  137. data/plugins/security/readonly_wiki.rb +25 -0
  138. data/plugins/security/stack.rb +20 -0
  139. data/plugins/security/yamlfile.rb +66 -0
  140. data/plugins/tags/code.rb +6 -0
  141. data/plugins/tags/footnotes.rb +35 -0
  142. data/plugins/tags/gist-embed.css +123 -0
  143. data/plugins/tags/gist.rb +13 -0
  144. data/plugins/tags/html.rb +57 -0
  145. data/plugins/tags/include.rb +20 -0
  146. data/plugins/tags/main.rb +353 -0
  147. data/plugins/tags/math.rb +117 -0
  148. data/plugins/tags/scripting.rb +64 -0
  149. data/plugins/tags/sort.rb +7 -0
  150. data/plugins/tags/tabs.rb +20 -0
  151. data/plugins/treeview/images/collapsed.png +0 -0
  152. data/plugins/treeview/images/expanded.png +0 -0
  153. data/plugins/treeview/images/menu.png +0 -0
  154. data/plugins/treeview/images/tree.png +0 -0
  155. data/plugins/treeview/images/wait.gif +0 -0
  156. data/plugins/treeview/main.rb +16 -0
  157. data/plugins/treeview/script.js +5 -0
  158. data/plugins/treeview/script/00-jquery.treeview.js +164 -0
  159. data/plugins/treeview/script/init.js +25 -0
  160. data/plugins/treeview/treeview.css +1 -0
  161. data/plugins/treeview/treeview.scss +113 -0
  162. data/plugins/utils/assets.rb +74 -0
  163. data/plugins/utils/cache.rb +53 -0
  164. data/plugins/utils/image_magick.rb +34 -0
  165. data/plugins/utils/pygments.css +1 -0
  166. data/plugins/utils/pygments.rb +50 -0
  167. data/plugins/utils/pygments.scss +83 -0
  168. data/plugins/utils/semaphore.rb +50 -0
  169. data/plugins/utils/shell.rb +45 -0
  170. data/plugins/utils/store.rb +315 -0
  171. data/plugins/utils/worker.rb +36 -0
  172. data/plugins/utils/xml.rb +29 -0
  173. data/static/images/favicon.png +0 -0
  174. data/static/script.js +267 -0
  175. data/static/script/00-json2.js +486 -0
  176. data/static/script/01-jstorage.js +217 -0
  177. data/static/script/02-jquery.js +9440 -0
  178. data/static/script/03-jquery.ui.core.js +337 -0
  179. data/static/script/04-jquery.ui.widget.js +502 -0
  180. data/static/script/05-jquery.ui.position.js +517 -0
  181. data/static/script/06-jquery.ui.menu.js +609 -0
  182. data/static/script/07-jquery.ui.autocomplete.js +601 -0
  183. data/static/script/08-olelo.i18n.js +37 -0
  184. data/static/script/09-olelo.unsaved.js +68 -0
  185. data/static/script/10-olelo.historytable.js +40 -0
  186. data/static/script/11-olelo.pagination.js +18 -0
  187. data/static/script/13-olelo.tabwidget.js +57 -0
  188. data/static/script/14-olelo.timeago.js +70 -0
  189. data/static/script/15-olelo.underliner.js +31 -0
  190. data/static/script/16-olelo.ui.combobox.js +32 -0
  191. data/static/script/init.js +48 -0
  192. data/static/themes/atlantis/constants.scss +15 -0
  193. data/static/themes/atlantis/iehacks.scss +38 -0
  194. data/static/themes/atlantis/images/actions/delete.png +0 -0
  195. data/static/themes/atlantis/images/actions/edit.png +0 -0
  196. data/static/themes/atlantis/images/actions/history.png +0 -0
  197. data/static/themes/atlantis/images/actions/home.png +0 -0
  198. data/static/themes/atlantis/images/actions/move.png +0 -0
  199. data/static/themes/atlantis/images/actions/new.png +0 -0
  200. data/static/themes/atlantis/images/actions/page.png +0 -0
  201. data/static/themes/atlantis/images/bg/button.png +0 -0
  202. data/static/themes/atlantis/images/bg/container.png +0 -0
  203. data/static/themes/atlantis/images/bg/content.png +0 -0
  204. data/static/themes/atlantis/images/bg/footer.png +0 -0
  205. data/static/themes/atlantis/images/bg/header.jpg +0 -0
  206. data/static/themes/atlantis/images/bg/header.orig.jpg +0 -0
  207. data/static/themes/atlantis/images/bg/header_gray.jpg +0 -0
  208. data/static/themes/atlantis/images/bug.png +0 -0
  209. data/static/themes/atlantis/images/filetypes/7z.png +0 -0
  210. data/static/themes/atlantis/images/filetypes/_archive.png +0 -0
  211. data/static/themes/atlantis/images/filetypes/_audio.png +0 -0
  212. data/static/themes/atlantis/images/filetypes/_code.png +0 -0
  213. data/static/themes/atlantis/images/filetypes/_linux.png +0 -0
  214. data/static/themes/atlantis/images/filetypes/_picture.png +0 -0
  215. data/static/themes/atlantis/images/filetypes/_video.png +0 -0
  216. data/static/themes/atlantis/images/filetypes/bz2.png +0 -0
  217. data/static/themes/atlantis/images/filetypes/doc.png +0 -0
  218. data/static/themes/atlantis/images/filetypes/flac.png +0 -0
  219. data/static/themes/atlantis/images/filetypes/gz.png +0 -0
  220. data/static/themes/atlantis/images/filetypes/html.png +0 -0
  221. data/static/themes/atlantis/images/filetypes/java.png +0 -0
  222. data/static/themes/atlantis/images/filetypes/jpg.png +0 -0
  223. data/static/themes/atlantis/images/filetypes/midi.png +0 -0
  224. data/static/themes/atlantis/images/filetypes/mp3.png +0 -0
  225. data/static/themes/atlantis/images/filetypes/ogg.png +0 -0
  226. data/static/themes/atlantis/images/filetypes/pdf.png +0 -0
  227. data/static/themes/atlantis/images/filetypes/php.png +0 -0
  228. data/static/themes/atlantis/images/filetypes/png.png +0 -0
  229. data/static/themes/atlantis/images/filetypes/ppt.png +0 -0
  230. data/static/themes/atlantis/images/filetypes/psd.png +0 -0
  231. data/static/themes/atlantis/images/filetypes/rar.png +0 -0
  232. data/static/themes/atlantis/images/filetypes/rb.png +0 -0
  233. data/static/themes/atlantis/images/filetypes/sh.png +0 -0
  234. data/static/themes/atlantis/images/filetypes/tar.png +0 -0
  235. data/static/themes/atlantis/images/filetypes/txt.png +0 -0
  236. data/static/themes/atlantis/images/filetypes/wma.png +0 -0
  237. data/static/themes/atlantis/images/filetypes/xls.png +0 -0
  238. data/static/themes/atlantis/images/filetypes/zip.png +0 -0
  239. data/static/themes/atlantis/images/folder.png +0 -0
  240. data/static/themes/atlantis/images/folder_open.png +0 -0
  241. data/static/themes/atlantis/images/loading.gif +0 -0
  242. data/static/themes/atlantis/images/loading.xcf +0 -0
  243. data/static/themes/atlantis/images/not_found.png +0 -0
  244. data/static/themes/atlantis/images/page.png +0 -0
  245. data/static/themes/atlantis/images/search.png +0 -0
  246. data/static/themes/atlantis/layout.scss +115 -0
  247. data/static/themes/atlantis/menu.scss +99 -0
  248. data/static/themes/atlantis/print.scss +129 -0
  249. data/static/themes/atlantis/screen.scss +495 -0
  250. data/static/themes/atlantis/style.css +3 -0
  251. data/static/themes/lib/autocomplete.scss +39 -0
  252. data/static/themes/lib/headlines.scss +10 -0
  253. data/static/themes/lib/horizontal-list.scss +31 -0
  254. data/static/themes/lib/patch.scss +88 -0
  255. data/static/themes/lib/reset.scss +114 -0
  256. data/static/themes/lib/rounded.scss +46 -0
  257. data/static/themes/lib/shadow.scss +14 -0
  258. data/test/config_test.rb +28 -0
  259. data/test/factory_test.rb +29 -0
  260. data/test/hash_extensions_test.rb +16 -0
  261. data/test/helper.rb +38 -0
  262. data/test/hooks_test.rb +85 -0
  263. data/test/object_extensions_test.rb +20 -0
  264. data/test/page_test.rb +168 -0
  265. data/test/request_test.rb +166 -0
  266. data/test/string_extensions_test.rb +32 -0
  267. data/test/templates_test.rb +39 -0
  268. data/test/util_test.rb +71 -0
  269. data/views/changes.slim +22 -0
  270. data/views/compare.slim +8 -0
  271. data/views/delete.slim +9 -0
  272. data/views/deleted.slim +2 -0
  273. data/views/edit.slim +65 -0
  274. data/views/error.slim +6 -0
  275. data/views/history.slim +20 -0
  276. data/views/layout.slim +38 -0
  277. data/views/login.slim +37 -0
  278. data/views/move.slim +10 -0
  279. data/views/not_found.slim +6 -0
  280. data/views/profile.slim +26 -0
  281. data/views/show.slim +9 -0
  282. metadata +488 -0
@@ -0,0 +1,64 @@
1
+ description 'Scripting tags'
2
+ require 'evaluator'
3
+
4
+ Tag.define :value, :requires => :of, :immediate => true, :description => 'Print value' do |context, attrs|
5
+ Evaluator.eval(attrs['of'], context.params)
6
+ end
7
+
8
+ Tag.define :def, :optional => %w(value args), :requires => :name,
9
+ :immediate => true, :description => 'Define variable' do |context, attrs, content|
10
+ name = attrs['name'].downcase
11
+ if attrs['value']
12
+ context.params[name] = Evaluator.eval(attrs['value'], context.params)
13
+ else
14
+ functions = context[:functions] ||= {}
15
+ functions[name] = [attrs['args'].to_s.split(/\s+/), content]
16
+ end
17
+ nil
18
+ end
19
+
20
+ Tag.define :call, :optional => '*', :requires => :name, :immediate => true, :description => 'Call function' do |context, attrs|
21
+ name = attrs['name'].downcase
22
+ functions = context[:functions]
23
+ raise NameError, "Function #{name} not found" if !functions || !functions[name]
24
+ args, content = functions[name]
25
+ args = args.inject({}) do |hash, arg|
26
+ raise ArgumentError, "Argument #{arg} is required" if !attrs[arg]
27
+ hash[arg] = Evaluator.eval(attrs[arg], context.params)
28
+ hash
29
+ end
30
+ result = nested_tags(context.subcontext(:params => args), content)
31
+ if attrs['result']
32
+ context.params[attrs['result']] = result
33
+ nil
34
+ else
35
+ result
36
+ end
37
+ end
38
+
39
+ Tag.define :for, :optional => :counter, :requires => %w(from to),
40
+ :immediate => true, :limit => 50, :description => 'For loop' do |context, attrs, content|
41
+ to = attrs['to'].to_i
42
+ from = attrs['from'].to_i
43
+ raise 'Limits exceeded' if to - from > 10
44
+ (from..to).map do |i|
45
+ params = attrs['counter'] ? {attrs['counter'] => i} : {}
46
+ nested_tags(context.subcontext(:params => params), content)
47
+ end.join
48
+ end
49
+
50
+ Tag.define :repeat, :optional => :counter, :requires => :times,
51
+ :immediate => true, :limit => 50, :description => 'Repeat loop' do |context, attrs, content|
52
+ n = attrs['times'].to_i
53
+ raise 'Limits exceeded' if n > 10
54
+ (1..n).map do |i|
55
+ params = attrs['counter'] ? {attrs['counter'] => i} : {}
56
+ nested_tags(context.subcontext(:params => params), content)
57
+ end.join
58
+ end
59
+
60
+ Tag.define :if, :requires => :test, :immediate => true, :description => 'If statement' do |context, attrs, content|
61
+ if Evaluator.eval(attrs['test'], context.params)
62
+ nested_tags(context.subcontext, content)
63
+ end
64
+ end
@@ -0,0 +1,7 @@
1
+ description 'Tag which creates sorted list'
2
+
3
+ Tag.define :sort, :optional => %w(ordered descending) do |context, attrs, content|
4
+ type = attrs['ordered'] == 'ordered' ? 'ol' : 'ul'
5
+ order = attrs['descending'] == 'descending' ? -1 : 1
6
+ %{<#{type}>#{content.strip.split(/\n/).sort {|a,b| (a <=> b) * order }.map {|x| "<li>#{escape_html x}</li>"}.join}</#{type}>}
7
+ end
@@ -0,0 +1,20 @@
1
+ description 'Tabs'
2
+
3
+ Tag.define :tabs do |context, attrs, content|
4
+ tabs = context[:tabs] = []
5
+ prefix = (context[:tabs_prefix] ||= 0)
6
+ content = subfilter(context, content)
7
+ li = []
8
+ tabs.each_with_index do |name, i|
9
+ li << %{<li id="tabhead-#{prefix}-#{i}"><a href="#tab-#{prefix}-#{i}">#{escape_html name}</a></li>}
10
+ end
11
+ context.private.delete(:tabs)
12
+ context[:tabs_prefix] += 1
13
+ %{<ul class="tabs">#{li.join}</ul>} + content
14
+ end
15
+
16
+ Tag.define :tab, :requires => :name do |context, attrs, content|
17
+ raise '<tab> can only be used in <tabs>' if !context[:tabs]
18
+ context[:tabs] << attrs['name']
19
+ %{<div class="tab" id="tab-#{context[:tabs_prefix]}-#{context[:tabs].size - 1}">#{subfilter(context, content)}</div>}
20
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,16 @@
1
+ description 'Tree Viewer'
2
+ dependencies 'aspects', 'utils/assets'
3
+ export_scripts '*.js', '*.css'
4
+ export_assets 'images/*'
5
+
6
+ Aspects::Aspect.create('treeview.json', :hidden => true, :cacheable => true, :mime => 'application/json; charset=utf-8') do
7
+ def call(context, page)
8
+ # Format [[has-children, classes, path, name], ...]
9
+ # Example: [[0, 'file-type-pdf', '/a/b.pdf', 'b.pdf'], ...]
10
+ page.children.map do |child|
11
+ classes = child.children.empty? ? 'page' : 'folder'
12
+ classes << " file-type-#{child.extension.downcase}" if !child.extension.empty?
13
+ [child.children.empty? ? 0 : 1, classes, build_path(child), child.name]
14
+ end.to_json
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ (function(c){c.fn.treeView=function(a){function l(b,e){if(a.stateStore){var d=jStorage.get(a.stateStore,[]);if(e)c.inArray(b,d)<0&&d.push(b);else d=c.grep(d,function(f){return f!=b});jStorage.set(a.stateStore,d)}}function m(b){var e=b[2],d=c('<li><div class="'+(b[0]?"hitarea collapsed":"placeholder")+'"><div class="arrow"/><div class="'+b[1]+'"/></div><a href="'+e+'">'+b[3]+"</a></li>"),f=d.children(".hitarea");d.data("name",b[3]);f.click(function(){if(f.hasClass("collapsed")){n(d,e);f.removeClass("collapsed").addClass("expanded")}else{d.children("ul").hide();
2
+ f.removeClass("expanded").addClass("collapsed")}l(e,f.hasClass("expanded"));return false});if(a.stateStore&&c.inArray(e,jStorage.get(a.stateStore,[]))>=0){n(d,e);f.removeClass("collapsed").addClass("expanded")}return d}function n(b,e){function d(i){var j=c("<ul/>");c.each(i,function(o,k){j.append(m(k))});e==a.root&&b.empty();b.children("ul").remove();b.append(j)}function f(i){g&&jStorage.set(g,i);var j={},o=[];c.each(i,function(k,h){j[h[3]]=h});c("> ul > li",b).each(function(){var k=c(this),h=k.data("name");
3
+ if(j[h])delete j[h];else k.remove();o.push(c(this))});c.each(j,function(k,h){var p=false;c.each(o,function(t,q){if(k<q.data("name")){p=true;q.before(m(h));return false}});p||b.children("ul").append(m(h))})}function r(){setTimeout(function(){a.ajax(e,f,function(){g&&jStorage.remove(g)})},a.delay)}var g=a.cacheStore?a.cacheStore+":"+e:null;if(b.children("ul").length!==0){b.children("ul").show();r()}else{var s=g?jStorage.get(g):null;if(s){d(s);r()}else{b.addClass("wait");a.ajax(e,function(i){b.removeClass("wait");
4
+ d(i);g&&jStorage.set(g,i)},function(){b.removeClass("wait")})}}}a||(a={});if(!a.root)a.root="/";if(!a.url)a.url="/treeview.json";if(!a.delay)a.delay=2E3;if(!a.ajax)a.ajax=function(b,e,d){c.ajax({url:a.url,data:{dir:b},success:e,error:d,dataType:"json"})};this.each(function(){n(c(this),a.root)})}})(jQuery);$.translations({en:{menu:"Menu",tree:"Tree"},de:{menu:"Men\u00fc",tree:"Baumansicht"},cs:{menu:"Menu",tree:"Strom"}});$("#sidebar").wrapInner('<div id="sidebar-menu"/>').prepend('<div id="sidebar-tree" style="display: none"><h1>'+$.t("tree")+'</h1><div id="treeview"/></div>');$("#menu > ul:first").prepend('<li class="selected" id="sidebar-tab-menu"><a href="#sidebar-menu">'+$.t("menu")+'</a></li><li id="sidebar-tab-tree"><a href="#sidebar-tree">'+$.t("tree")+"</a></li>");$("#sidebar-tab-menu, #sidebar-tab-tree").tabWidget({store:"sidebar-tab"});
5
+ $("#treeview").treeView({stateStore:"treeview-state",cacheStore:"treeview-cache",ajax:function(c,a,l){$.ajax({url:c,data:{aspect:"treeview.json"},success:a,error:l,dataType:"json"})}});
@@ -0,0 +1,164 @@
1
+ // Ajax Tree View
2
+ // Written by Daniel Mendler, 2009
3
+ (function($) {
4
+ // Create treeview
5
+ // $('div#id').treeView(...);
6
+ $.fn.treeView = function(options) {
7
+ if (!options) {
8
+ options = {};
9
+ }
10
+ if (!options.root) {
11
+ options.root = '/';
12
+ }
13
+ if (!options.url) {
14
+ options.url = '/treeview.json';
15
+ }
16
+ if (!options.delay) {
17
+ options.delay = 2000;
18
+ }
19
+ if (!options.ajax) {
20
+ options.ajax = function(path, success, error) {
21
+ $.ajax({url: options.url, data: { dir: path }, success: success, error: error, dataType: 'json'});
22
+ };
23
+ }
24
+
25
+ // Store if node is expanded
26
+ function setExpanded(path, expanded) {
27
+ if (options.stateStore) {
28
+ var state = jStorage.get(options.stateStore, []);
29
+ if (!expanded) {
30
+ state = $.grep(state, function(n, i) { return n != path; });
31
+ } else if ($.inArray(path, state) < 0) {
32
+ state.push(path);
33
+ }
34
+ jStorage.set(options.stateStore, state);
35
+ }
36
+ }
37
+
38
+ // Check if node is expanded
39
+ function isExpanded(path) {
40
+ return options.stateStore && $.inArray(path, jStorage.get(options.stateStore, [])) >= 0;
41
+ }
42
+
43
+ // Create child element.
44
+ // Data is array: [has-children, classes, path, name]
45
+ function createChild(data) {
46
+ var path = data[2],
47
+ child = $('<li><div class="'+(data[0] ? 'hitarea collapsed' : 'placeholder')+
48
+ '"><div class="arrow"/><div class="'+data[1]+'"/></div><a href="'+path+'">'+data[3]+'</a></li>'),
49
+ hitarea = child.children('.hitarea');
50
+ child.data('name', data[3]);
51
+ hitarea.click(function() {
52
+ if (hitarea.hasClass('collapsed')) {
53
+ openTree(child, path);
54
+ hitarea.removeClass('collapsed').addClass('expanded');
55
+ } else {
56
+ child.children('ul').hide();
57
+ hitarea.removeClass('expanded').addClass('collapsed');
58
+ }
59
+ setExpanded(path, hitarea.hasClass('expanded'));
60
+ return false;
61
+ });
62
+ if (isExpanded(path)) {
63
+ openTree(child, path);
64
+ hitarea.removeClass('collapsed').addClass('expanded');
65
+ }
66
+ return child;
67
+ }
68
+
69
+ // Open tree element with path
70
+ function openTree(element, path) {
71
+ // Cache key for cached json data
72
+ var cacheKey = options.cacheStore ? options.cacheStore + ':' + path : null;
73
+
74
+ // Store json in cache
75
+ function store(data) {
76
+ if (cacheKey) {
77
+ jStorage.set(cacheKey, data);
78
+ }
79
+ }
80
+
81
+ // Data loaded via ajax (callback) or from the cache
82
+ function dataLoaded(data) {
83
+ var ul = $('<ul/>');
84
+ $.each(data, function(i, child) { ul.append(createChild(child)); });
85
+ if (path == options.root) {
86
+ element.empty();
87
+ }
88
+ element.children('ul').remove();
89
+ element.append(ul);
90
+ }
91
+
92
+ // Data updated via ajax (callback)
93
+ function dataUpdated(data) {
94
+ store(data);
95
+
96
+ var exists = {}, list = [];
97
+ $.each(data, function(i, child) {
98
+ exists[child[3]] = child;
99
+ });
100
+ $('> ul > li', element).each(function() {
101
+ var li = $(this), name = li.data('name');
102
+ if (!exists[name]) {
103
+ li.remove();
104
+ } else {
105
+ delete exists[name];
106
+ }
107
+ list.push($(this));
108
+ });
109
+ $.each(exists, function(name, child) {
110
+ var inserted = false;
111
+ $.each(list, function(i, other) {
112
+ if (name < other.data('name')) {
113
+ inserted = true;
114
+ other.before(createChild(child));
115
+ return false;
116
+ }
117
+ });
118
+ if (!inserted) {
119
+ element.children('ul').append(createChild(child));
120
+ }
121
+ });
122
+ }
123
+
124
+ // Update this element with some delay
125
+ function update() {
126
+ setTimeout(function() {
127
+ options.ajax(path, dataUpdated, function() {
128
+ if (cacheKey) {
129
+ jStorage.remove(cacheKey);
130
+ }
131
+ });
132
+ }, options.delay);
133
+ }
134
+
135
+ // If children exist, show them and update this element
136
+ if (element.children('ul').length !== 0) {
137
+ element.children('ul').show();
138
+ update();
139
+ } else {
140
+ // Try to load from cache
141
+ var data = cacheKey ? jStorage.get(cacheKey) : null;
142
+ if (data) {
143
+ dataLoaded(data);
144
+ update();
145
+ }
146
+ // Load data via ajax and add busy indicator
147
+ else {
148
+ element.addClass('wait');
149
+ options.ajax(path, function(data) {
150
+ element.removeClass('wait');
151
+ dataLoaded(data);
152
+ store(data);
153
+ }, function() {
154
+ element.removeClass('wait');
155
+ });
156
+ }
157
+ }
158
+ }
159
+
160
+ this.each(function() {
161
+ openTree($(this), options.root);
162
+ });
163
+ };
164
+ })(jQuery);
@@ -0,0 +1,25 @@
1
+ // Add treeview translations
2
+ $.translations({
3
+ en: {
4
+ menu: 'Menu',
5
+ tree: 'Tree'
6
+ },
7
+ de: {
8
+ menu: 'Menü',
9
+ tree: 'Baumansicht'
10
+ },
11
+ cs: {
12
+ menu: 'Menu',
13
+ tree: 'Strom'
14
+ }
15
+ });
16
+
17
+ // Start tree view
18
+ $('#sidebar').wrapInner('<div id="sidebar-menu"/>').prepend('<div id="sidebar-tree" style="display: none"><h1>' + $.t('tree') +
19
+ '</h1><div id="treeview"/></div>');
20
+ $('#menu > ul:first').prepend('<li class="selected" id="sidebar-tab-menu"><a href="#sidebar-menu">' + $.t('menu') +
21
+ '</a></li><li id="sidebar-tab-tree"><a href="#sidebar-tree">' + $.t('tree') + '</a></li>');
22
+ $('#sidebar-tab-menu, #sidebar-tab-tree').tabWidget({store: 'sidebar-tab'});
23
+ $('#treeview').treeView({stateStore: 'treeview-state', cacheStore: 'treeview-cache', ajax: function(path, success, error) {
24
+ $.ajax({url: path, data: { aspect: 'treeview.json' }, success: success, error: error, dataType: 'json'});
25
+ }});
@@ -0,0 +1 @@
1
+ #sidebar-tab-menu a,#sidebar-tab-tree a{text-indent:-999px;width:16px}#sidebar-tab-menu.selected,#sidebar-tab-tree.selected{display:none !important}#sidebar-tab-menu{background:url(treeview/images/tree.png) no-repeat center center !important}#sidebar-tab-tree{background:url(treeview/images/menu.png) no-repeat center center !important}#treeview{position:relative;padding:0;margin:0;width:100%;max-height:600px;font-size:9pt;overflow:auto}#treeview .file-type-7z{background:url(../../static/themes/atlantis/images/filetypes/7z.png) no-repeat center center !important}#treeview .file-type-bz2{background:url(../../static/themes/atlantis/images/filetypes/bz2.png) no-repeat center center !important}#treeview .file-type-doc{background:url(../../static/themes/atlantis/images/filetypes/doc.png) no-repeat center center !important}#treeview .file-type-flac{background:url(../../static/themes/atlantis/images/filetypes/flac.png) no-repeat center center !important}#treeview .file-type-gz{background:url(../../static/themes/atlantis/images/filetypes/gz.png) no-repeat center center !important}#treeview .file-type-html{background:url(../../static/themes/atlantis/images/filetypes/html.png) no-repeat center center !important}#treeview .file-type-java{background:url(../../static/themes/atlantis/images/filetypes/java.png) no-repeat center center !important}#treeview .file-type-jpg{background:url(../../static/themes/atlantis/images/filetypes/jpg.png) no-repeat center center !important}#treeview .file-type-midi{background:url(../../static/themes/atlantis/images/filetypes/midi.png) no-repeat center center !important}#treeview .file-type-mp3{background:url(../../static/themes/atlantis/images/filetypes/mp3.png) no-repeat center center !important}#treeview .file-type-ogg{background:url(../../static/themes/atlantis/images/filetypes/ogg.png) no-repeat center center !important}#treeview .file-type-pdf{background:url(../../static/themes/atlantis/images/filetypes/pdf.png) no-repeat center center !important}#treeview .file-type-php{background:url(../../static/themes/atlantis/images/filetypes/php.png) no-repeat center center !important}#treeview .file-type-png{background:url(../../static/themes/atlantis/images/filetypes/png.png) no-repeat center center !important}#treeview .file-type-ppt{background:url(../../static/themes/atlantis/images/filetypes/ppt.png) no-repeat center center !important}#treeview .file-type-psd{background:url(../../static/themes/atlantis/images/filetypes/psd.png) no-repeat center center !important}#treeview .file-type-rar{background:url(../../static/themes/atlantis/images/filetypes/rar.png) no-repeat center center !important}#treeview .file-type-rb{background:url(../../static/themes/atlantis/images/filetypes/rb.png) no-repeat center center !important}#treeview .file-type-sh{background:url(../../static/themes/atlantis/images/filetypes/sh.png) no-repeat center center !important}#treeview .file-type-tar{background:url(../../static/themes/atlantis/images/filetypes/tar.png) no-repeat center center !important}#treeview .file-type-txt{background:url(../../static/themes/atlantis/images/filetypes/txt.png) no-repeat center center !important}#treeview .file-type-wma{background:url(../../static/themes/atlantis/images/filetypes/wma.png) no-repeat center center !important}#treeview .file-type-xls{background:url(../../static/themes/atlantis/images/filetypes/xls.png) no-repeat center center !important}#treeview .file-type-zip{background:url(../../static/themes/atlantis/images/filetypes/zip.png) no-repeat center center !important}#treeview ul{list-style:none;display:block;clear:both}#treeview ul li{border:none !important;text-indent:0 !important;clear:both}#treeview ul li li{margin:0;padding:0 1em !important}#treeview ul li a,#treeview ul li a:active,#treeview ul li a:hover{font-size:90% !important;font-variant:normal;text-indent:0 !important;margin:0 !important;padding:0 !important;float:left;width:1px;overflow:visible;white-space:nowrap !important;color:#333333;background:transparent}#treeview ul li .hitarea,#treeview ul li .placeholder{width:32px;height:16px;cursor:pointer;float:left}#treeview ul li .hitarea div,#treeview ul li .placeholder div{width:16px;height:16px;float:left}#treeview ul .wait .arrow{background:url(treeview/images/wait.gif) no-repeat center center !important}#treeview ul .collapsed .arrow{background:url(treeview/images/collapsed.png) no-repeat center center}#treeview ul .expanded .arrow{background:url(treeview/images/expanded.png) no-repeat center center}#treeview ul .page{background:url(../../static/themes/atlantis/images/page.png) no-repeat center center}#treeview ul .expanded .folder{background:url(../../static/themes/atlantis/images/folder_open.png) no-repeat center center}#treeview ul .collapsed .folder{background:url(../../static/themes/atlantis/images/folder.png) no-repeat center center}
@@ -0,0 +1,113 @@
1
+ #sidebar-tab-menu, #sidebar-tab-tree {
2
+ a {
3
+ text-indent: -999px;
4
+ width: 16px;
5
+ }
6
+ &.selected {
7
+ display: none !important;
8
+ }
9
+ }
10
+
11
+ #sidebar-tab-menu {
12
+ background: url(treeview/images/tree.png) no-repeat center center !important;
13
+ }
14
+
15
+ #sidebar-tab-tree {
16
+ background: url(treeview/images/menu.png) no-repeat center center !important;
17
+ }
18
+
19
+ @mixin file-type($type) {
20
+ .file-type-#{$type} {
21
+ background: url(../../static/themes/atlantis/images/filetypes/#{$type}.png) no-repeat center center !important;
22
+ }
23
+ }
24
+
25
+ #treeview {
26
+ @include file-type("7z");
27
+ @include file-type("bz2");
28
+ @include file-type("doc");
29
+ @include file-type("flac");
30
+ @include file-type("gz");
31
+ @include file-type("html");
32
+ @include file-type("java");
33
+ @include file-type("jpg");
34
+ @include file-type("midi");
35
+ @include file-type("mp3");
36
+ @include file-type("ogg");
37
+ @include file-type("pdf");
38
+ @include file-type("php");
39
+ @include file-type("png");
40
+ @include file-type("ppt");
41
+ @include file-type("psd");
42
+ @include file-type("rar");
43
+ @include file-type("rb");
44
+ @include file-type("sh");
45
+ @include file-type("tar");
46
+ @include file-type("txt");
47
+ @include file-type("wma");
48
+ @include file-type("xls");
49
+ @include file-type("zip");
50
+ position: relative;
51
+ padding: 0;
52
+ margin: 0;
53
+ width: 100%;
54
+ max-height: 600px;
55
+ font-size: 9pt;
56
+ overflow: auto;
57
+ ul {
58
+ list-style: none;
59
+ display: block;
60
+ clear: both;
61
+ li {
62
+ border: none !important;
63
+ text-indent: 0 !important;
64
+ clear: both;
65
+ li {
66
+ margin: 0;
67
+ padding: 0 1em !important;
68
+ }
69
+ a, a:active, a:hover {
70
+ font-size: 90% !important;
71
+ font-variant: normal;
72
+ text-indent: 0 !important;
73
+ margin: 0 !important;
74
+ padding: 0 !important;
75
+ float: left;
76
+ width: 1px;
77
+ overflow: visible;
78
+ white-space: nowrap !important;
79
+ color: #333333;
80
+ background: transparent;
81
+ }
82
+ .hitarea, .placeholder {
83
+ width: 32px;
84
+ height: 16px;
85
+ cursor: pointer;
86
+ float: left;
87
+ div {
88
+ width: 16px;
89
+ height: 16px;
90
+ float: left;
91
+ }
92
+ }
93
+ }
94
+ .wait .arrow {
95
+ background: url(treeview/images/wait.gif) no-repeat center center !important;
96
+ }
97
+ .collapsed .arrow {
98
+ background: url(treeview/images/collapsed.png) no-repeat center center;
99
+ }
100
+ .expanded .arrow {
101
+ background: url(treeview/images/expanded.png) no-repeat center center;
102
+ }
103
+ .page {
104
+ background: url(../../static/themes/atlantis/images/page.png) no-repeat center center;
105
+ }
106
+ .expanded .folder {
107
+ background: url(../../static/themes/atlantis/images/folder_open.png) no-repeat center center;
108
+ }
109
+ .collapsed .folder {
110
+ background: url(../../static/themes/atlantis/images/folder.png) no-repeat center center;
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,74 @@
1
+ description 'Asset manager'
2
+
3
+ class ::Olelo::Application
4
+ @assets = {}
5
+ @scripts = {}
6
+
7
+ class << self
8
+ attr_reader :assets, :scripts
9
+ end
10
+
11
+ attr_reader? :disable_assets
12
+
13
+ hook :script, 1 do
14
+ js = Application.scripts['js']
15
+ if js && !disable_assets?
16
+ path = build_path "_/assets/assets.js?#{js.first.to_i}"
17
+ %{<script src="#{escape_html path}" type="text/javascript"/>}
18
+ end
19
+ end
20
+
21
+ hook :head, 1 do
22
+ css = Application.scripts['css']
23
+ if css && !disable_assets?
24
+ path = build_path "_/assets/assets.css?#{css.first.to_i}"
25
+ %{<link rel="stylesheet" href="#{escape_html path}" type="text/css"/>}
26
+ end
27
+ end
28
+
29
+ get "/_/assets/assets.:type", :type => 'js|css' do
30
+ if script = Application.scripts[params[:type]]
31
+ cache_control :last_modified => script.first, :max_age => :static
32
+ response['Content-Type'] = MimeMagic.by_extension(params[:type]).to_s
33
+ response['Content-Length'] = script.last.bytesize.to_s
34
+ script.last
35
+ else
36
+ :not_found
37
+ end
38
+ end
39
+
40
+ get "/_/assets/:name", :name => '.*' do
41
+ if asset = Application.assets[params[:name]]
42
+ cache_control :last_modified => asset.mtime, :max_age => :static
43
+ response['Content-Type'] = asset.mime.to_s
44
+ response['Content-Length'] = asset.size.to_s
45
+ halt asset.open
46
+ else
47
+ :not_found
48
+ end
49
+ end
50
+ end
51
+
52
+ class ::Olelo::Plugin
53
+ def export_assets(*files)
54
+ virtual_fs.glob(*files) do |file|
55
+ Application.assets[plugin_dir/file.name] = file
56
+ end
57
+ end
58
+
59
+ def export_scripts(*files)
60
+ virtual_fs.glob(*files) do |file|
61
+ raise 'Invalid script type' if file.name !~ /\.(css|js)$/
62
+ scripts = Application.scripts[$1].to_a
63
+ Application.scripts[$1] = [[scripts[0], file.mtime].compact.max, "#{scripts[1]}/* #{plugin_dir/file.name} */\n#{file.read}\n"]
64
+ end
65
+ end
66
+
67
+ def plugin_dir
68
+ if File.basename(file) == 'main.rb'
69
+ path
70
+ else
71
+ File.dirname(path)
72
+ end
73
+ end
74
+ end