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,12 @@
1
+ en:
2
+ full_article: 'Full Article'
3
+ written_by: 'written by #{author}'
4
+ no_articles: 'No articles found'
5
+ de:
6
+ full_article: 'Ganzer Artikel'
7
+ written_by: 'verfasst von #{author}'
8
+ no_articles: 'Keine Artikel gefunden'
9
+ cs_CZ:
10
+ full_article: 'Plný článek'
11
+ written_by: 'Napsal: #{author}'
12
+ no_articles: 'Žádné články nenalezeny'
@@ -0,0 +1,85 @@
1
+ description 'Blog aspect'
2
+ dependencies 'tags', 'utils/assets', 'utils/xml'
3
+ export_scripts '*.css'
4
+
5
+ Application.get '(/:path)/:year(/:month)', :year => '20\d{2}', :month => '(?:0[1-9])|(?:1[1-2])' do
6
+ params[:aspect] = 'blog'
7
+ send('GET /')
8
+ end
9
+
10
+ Tags::Tag.define 'menu', :optional => :path, :description => 'Show blog menu', :dynamic => true do |context, attrs, content|
11
+ page = Page.find(attrs[:path]) rescue nil
12
+ if page
13
+ Cache.cache("blog-#{page.path}-#{page.version.cache_id}", :update => context.request.no_cache?, :defer => true) do
14
+ years = {}
15
+ page.children.each do |child|
16
+ (years[child.version.date.year] ||= [])[child.version.date.month] = true
17
+ end
18
+ render :menu, :locals => {:years => years, :page => page}
19
+ end
20
+ end
21
+ end
22
+
23
+ Aspects::Aspect.create(:blog, :priority => 3, :layout => true, :cacheable => true, :hidden => true) do
24
+ def accepts?(page); !page.children.empty?; end
25
+ def call(context, page)
26
+ @page = page
27
+ articles = page.children.sort_by {|child| -child.version.date.to_i }
28
+
29
+ year = context.params[:year].to_i
30
+ articles.reject! {|article| article.version.date.year != year } if year != 0
31
+ month = context.params[:month].to_i
32
+ articles.reject! {|article| article.version.date.month != month } if month != 0
33
+
34
+ @page_nr = [context.params[:page].to_i, 1].max
35
+ per_page = 10
36
+ @page_count = articles.size / per_page + 1
37
+ articles = articles[((@page_nr - 1) * per_page) ... (@page_nr * per_page)].to_a
38
+
39
+ @articles = articles.map do |page|
40
+ begin
41
+ subctx = context.subcontext(:page => page, :params => {:included => true})
42
+ content = Aspects::Aspect.find!(page, :layout => true).call(subctx, page)
43
+ if !context.params[:full]
44
+ paragraphs = XML::Fragment(content).xpath('p')
45
+ content = ''
46
+ paragraphs.each do |p|
47
+ content += p.to_xhtml
48
+ break if content.length > 10000
49
+ end
50
+ end
51
+ rescue Aspects::Aspect::NotAvailable => ex
52
+ %{<span class="error">#{escape_html ex.message}</span>}
53
+ end
54
+ [page, content]
55
+ end
56
+ render :blog, :locals => {:full => context.params[:full]}
57
+ end
58
+ end
59
+
60
+ __END__
61
+ @@ blog.slim
62
+ - if @articles.empty?
63
+ .error= :no_articles.t
64
+ - else
65
+ .blog
66
+ - @articles.each do |page, content|
67
+ .article
68
+ h2
69
+ a.name href=build_path(page) = page.name
70
+ .date= date page.version.date
71
+ .author= :written_by.t(:author => page.version.author.name)
72
+ .content== content
73
+ - if !full
74
+ a.full href=build_path(page.path) = :full_article.t
75
+ = pagination(@page, @page_count, @page_nr, :aspect => 'blog')
76
+ @@ menu.slim
77
+ table.blog-menu
78
+ - years.keys.sort.each do |year|
79
+ tr
80
+ td
81
+ a href=build_path(page.path/year) = year
82
+ td
83
+ - (1..12).select {|m| years[year][m] }.each do |month|
84
+ - m = '%02d' % month
85
+ a href=build_path(page.path/year/m) = m
@@ -0,0 +1,18 @@
1
+ en:
2
+ captcha: 'Captcha:'
3
+ enter_captcha: 'Please enter the captcha.'
4
+ captcha_invalid: Invalid captcha
5
+ captcha_valid: Valid captcha
6
+ preview: Preview
7
+ de:
8
+ captcha: 'Captcha:'
9
+ enter_captcha: 'Bitte geben Sie ein Captcha ein.'
10
+ captcha_invalid: 'Ungültiges Captcha'
11
+ captcha_valid: 'Gültiges Captcha'
12
+ preview: Vorschau
13
+ cs_CZ:
14
+ captcha: 'Captcha:'
15
+ enter_captcha: 'Vložte laskavě captcha kód.'
16
+ captcha_invalid: 'Neplatný captcha kód'
17
+ captcha_valid: 'Platný captcha kód'
18
+ preview: 'Náhled'
@@ -0,0 +1,3 @@
1
+ description 'Markup editor'
2
+ dependencies 'misc/variables', 'utils/assets'
3
+ export_scripts '*.js'
@@ -0,0 +1,10 @@
1
+ (function(){var i=function(){var f=typeof document.selection!=="undefined"&&typeof document.selection.createRange!=="undefined";return{getSelectionRange:function(a){var b,c,d;a.focus();if(typeof a.selectionStart!=="undefined"){b=a.selectionStart;c=a.selectionEnd}else if(f){b=document.selection.createRange();c=b.text.length;if(b.parentElement()!==a)throw"Unable to get selection range.";if(a.type==="textarea"){d=b.duplicate();d.moveToElementText(a);d.setEndPoint("EndToEnd",b);b=d.text.length-c}else{a=
2
+ a.createTextRange();a.setEndPoint("EndToStart",b);b=a.text.length}c=b+c}else throw"Unable to get selection range.";return{start:b,end:c}},getSelectionStart:function(a){return this.getSelectionRange(a).start},getSelectionEnd:function(a){return this.getSelectionRange(a).end},setSelectionRange:function(a,b,c){var d;a.focus();if(typeof c==="undefined")c=b;if(typeof a.selectionStart!=="undefined")a.setSelectionRange(b,c);else if(f){d=a.value;a=a.createTextRange();c-=b+d.slice(b+1,c).split("\n").length-
3
+ 1;b-=d.slice(0,b).split("\n").length-1;a.move("character",b);a.moveEnd("character",c);a.select()}else throw"Unable to set selection range.";},getSelectedText:function(a){var b=this.getSelectionRange(a);return a.value.substring(b.start,b.end)},insertText:function(a,b,c,d,g){d=d||c;var h=c+b.length,l=a.value.substring(0,c);d=a.value.substr(d);a.value=l+b+d;g===true?this.setSelectionRange(a,c,h):this.setSelectionRange(a,h)},replaceSelectedText:function(a,b,c){var d=this.getSelectionRange(a);this.insertText(a,
4
+ b,d.start,d.end,c)},wrapSelectedText:function(a,b,c,d){b=b+this.getSelectedText(a)+c;this.replaceSelectedText(a,b,d)}}}();window.Selection=i})();
5
+ (function(i){i.fn.extend({getSelectionRange:function(){return Selection.getSelectionRange(this[0])},getSelectionStart:function(){return Selection.getSelectionStart(this[0])},getSelectionEnd:function(){return Selection.getSelectionEnd(this[0])},getSelectedText:function(){return Selection.getSelectedText(this[0])},setSelectionRange:function(f,a){return this.each(function(){Selection.setSelectionRange(this,f,a)})},insertText:function(f,a,b,c){return this.each(function(){Selection.insertText(this,f,a,
6
+ b,c)})},replaceSelectedText:function(f,a){return this.each(function(){Selection.replaceSelectedText(this,f,a)})},wrapSelectedText:function(f,a,b){return this.each(function(){Selection.wrapSelectedText(this,f,a,b)})}})})(jQuery);(function(i){var f={creole:{link:["[[","link text","]]"],bold:["**","bold text","**"],italic:["//","italic text","//"],ul:["* ","list item","",true],ol:["# ","list item","",true],h1:["= ","headline","",true],h2:["== ","headline","",true],h3:["=== ","headline","",true],sub:["~~","subscript","~~"],sup:["^^","superscript","^^"],del:["--","deleted text","--"],ins:["++","inserted text","++"],image:["{{","image","}}"],preformatted:["{{{","preformatted","}}}"]},markdown:{link:function(a){return(a=prompt("link target:",
7
+ a))?["[","link text","]("+a+")"]:null},bold:["**","bold text","**"],italic:["*","italic text","*"],ul:["* ","list item","",true],ol:["1. ","list item","",true],h1:["","headline","\n========",true],h2:["","headline","\n--------",true],image:function(a){return(a=prompt("image path:",a))?["![","image alt text","]("+a+")"]:null},preformatted:[" ","preformatted","",true]},orgmode:{bold:["*","bold text","*"],italic:["/","italic text","/"],ul:["- ","list item",""],ol:["1. ","list item",""],h1:["* ","headline",
8
+ ""],h2:["** ","headline",""],h3:["*** ","headline",""]},textile:{link:function(a){return(a=prompt("link target:",a))?['"',"link text",'":'+a]:null},bold:["*","bold text","*"],italic:["_","italic text","_"],ul:["* ","list item","",true],ol:["# ","list item","",true],h1:["h1. ","headline","",true],h2:["h2. ","headline","",true],h3:["h3. ","headline","",true],em:["_","emphasized text","_"],sub:["~","subscript","~"],sup:["^","superscript","^"],del:["-","deleted text","-"],ins:["+","inserted text","+"],
9
+ image:["!","image","!"]}};i.fn.markupEditor=function(a){if(a=f[a]){var b=i('<ul class="button-bar" id="markup-editor"/>'),c=[];for(k in a)c.push(k);c.sort();for(var d=0;d<c.length;++d)b.append('<li><a href="#" id="markup-editor-'+c[d]+'">'+c[d]+"</a></li>");this.before(b);var g=this;i("a",b).click(function(){var h=a[this.id.substr(14)],l=g.getSelectedText();if(typeof h=="function")h=h(l);if(h){var e=g.getSelectionRange(),j=h[0],n=h[1],m=h[2];if(h[3]){g.setSelectionRange(e.start-1,e.start);if(e.start!==
10
+ 0&&g.getSelectedText()!="\n")j="\n"+j;g.setSelectionRange(e.end,e.end+1);if(g.getSelectedText()!="\n")m+="\n"}if(e.start==e.end){g.insertText(j+n+m,e.start,e.start,false);g.setSelectionRange(e.start+j.length,e.start+j.length+n.length)}else g.insertText(j+l+m,e.start,e.end,false)}return false})}}})(jQuery);if(window.Olelo){var mime=Olelo.page_mime;if(mime=="application/x-empty"||mime=="inode/directory")mime=Olelo.default_mime;var match=/text\/x-(\w+)/.exec(mime);match&&$("#edit-content").markupEditor(match[1])};
@@ -0,0 +1,267 @@
1
+ // jquery-text-selection 1.0
2
+ (function() {
3
+
4
+ /**
5
+ *
6
+ */
7
+ var Selection = (function() {
8
+
9
+ var hasRange = (typeof document.selection !== 'undefined' && typeof document.selection.createRange !== 'undefined');
10
+
11
+ return {
12
+
13
+ /**
14
+ *
15
+ */
16
+ getSelectionRange: function(el) {
17
+
18
+ var start,
19
+ end,
20
+ range,
21
+ rangeLength,
22
+ duplicateRange,
23
+ textRange;
24
+
25
+ el.focus();
26
+
27
+ // Mozilla / Safari
28
+ if (typeof el.selectionStart !== 'undefined') {
29
+
30
+ start = el.selectionStart;
31
+ end = el.selectionEnd;
32
+
33
+ // IE
34
+ } else if (hasRange) {
35
+
36
+ range = document.selection.createRange();
37
+ rangeLength = range.text.length;
38
+
39
+ if(range.parentElement() !== el) {
40
+ throw('Unable to get selection range.');
41
+ }
42
+
43
+ // Textarea
44
+ if (el.type === 'textarea') {
45
+
46
+ duplicateRange = range.duplicate();
47
+ duplicateRange.moveToElementText(el);
48
+ duplicateRange.setEndPoint('EndToEnd', range);
49
+
50
+ start = duplicateRange.text.length - rangeLength;
51
+
52
+ // Text Input
53
+ } else {
54
+
55
+ textRange = el.createTextRange();
56
+ textRange.setEndPoint("EndToStart", range);
57
+
58
+ start = textRange.text.length;
59
+ }
60
+
61
+ end = start + rangeLength;
62
+
63
+ // Unsupported type
64
+ } else {
65
+ throw('Unable to get selection range.');
66
+ }
67
+
68
+ return {
69
+ start: start,
70
+ end: end
71
+ };
72
+ },
73
+
74
+
75
+ /**
76
+ *
77
+ */
78
+ getSelectionStart: function(el) {
79
+ return this.getSelectionRange(el).start;
80
+ },
81
+
82
+
83
+ /**
84
+ *
85
+ */
86
+ getSelectionEnd: function(el) {
87
+ return this.getSelectionRange(el).end;
88
+ },
89
+
90
+
91
+ /**
92
+ *
93
+ */
94
+ setSelectionRange: function(el, start, end) {
95
+
96
+ var value,
97
+ range;
98
+
99
+ el.focus();
100
+
101
+ if (typeof end === 'undefined') {
102
+ end = start;
103
+ }
104
+
105
+ // Mozilla / Safari
106
+ if (typeof el.selectionStart !== 'undefined') {
107
+
108
+ el.setSelectionRange(start, end);
109
+
110
+ // IE
111
+ } else if (hasRange) {
112
+
113
+ value = el.value;
114
+ range = el.createTextRange();
115
+ end -= start + value.slice(start + 1, end).split("\n").length - 1;
116
+ start -= value.slice(0, start).split("\n").length - 1;
117
+ range.move('character', start);
118
+ range.moveEnd('character', end);
119
+ range.select();
120
+
121
+ // Unsupported
122
+ } else {
123
+ throw('Unable to set selection range.');
124
+ }
125
+ },
126
+
127
+
128
+ /**
129
+ *
130
+ */
131
+ getSelectedText: function(el) {
132
+ var selection = this.getSelectionRange(el);
133
+ return el.value.substring(selection.start, selection.end);
134
+ },
135
+
136
+
137
+ /**
138
+ *
139
+ */
140
+ insertText: function(el, text, start, end, selectText) {
141
+
142
+ end = end || start;
143
+
144
+ var textLength = text.length,
145
+ selectionEnd = start + textLength,
146
+ beforeText = el.value.substring(0, start),
147
+ afterText = el.value.substr(end);
148
+
149
+ el.value = beforeText + text + afterText;
150
+
151
+ if (selectText === true) {
152
+ this.setSelectionRange(el, start, selectionEnd);
153
+ } else {
154
+ this.setSelectionRange(el, selectionEnd);
155
+ }
156
+ },
157
+
158
+
159
+ /**
160
+ *
161
+ */
162
+ replaceSelectedText: function(el, text, selectText) {
163
+ var selection = this.getSelectionRange(el);
164
+ this.insertText(el, text, selection.start, selection.end, selectText);
165
+ },
166
+
167
+
168
+ /**
169
+ *
170
+ */
171
+ wrapSelectedText: function(el, beforeText, afterText, selectText) {
172
+ var text = beforeText + this.getSelectedText(el) + afterText;
173
+ this.replaceSelectedText(el, text, selectText);
174
+ }
175
+
176
+ };
177
+ })();
178
+
179
+
180
+ /**
181
+ *
182
+ */
183
+ window.Selection = Selection;
184
+
185
+
186
+ })();
187
+
188
+ (function($) {
189
+
190
+
191
+ $.fn.extend({
192
+
193
+ /**
194
+ *
195
+ */
196
+ getSelectionRange: function() {
197
+ return Selection.getSelectionRange(this[0]);
198
+ },
199
+
200
+
201
+ /**
202
+ *
203
+ */
204
+ getSelectionStart: function() {
205
+ return Selection.getSelectionStart(this[0]);
206
+ },
207
+
208
+
209
+ /**
210
+ *
211
+ */
212
+ getSelectionEnd: function() {
213
+ return Selection.getSelectionEnd(this[0]);
214
+ },
215
+
216
+
217
+ /**
218
+ *
219
+ */
220
+ getSelectedText: function() {
221
+ return Selection.getSelectedText(this[0]);
222
+ },
223
+
224
+
225
+ /**
226
+ *
227
+ */
228
+ setSelectionRange: function(start, end) {
229
+ return this.each(function() {
230
+ Selection.setSelectionRange(this, start, end);
231
+ });
232
+ },
233
+
234
+
235
+ /**
236
+ *
237
+ */
238
+ insertText: function(text, start, end, selectText) {
239
+ return this.each(function() {
240
+ Selection.insertText(this, text, start, end, selectText);
241
+ });
242
+ },
243
+
244
+
245
+ /**
246
+ *
247
+ */
248
+ replaceSelectedText: function(text, selectText) {
249
+ return this.each(function() {
250
+ Selection.replaceSelectedText(this, text, selectText);
251
+ });
252
+ },
253
+
254
+
255
+ /**
256
+ *
257
+ */
258
+ wrapSelectedText: function(beforeText, afterText, selectText) {
259
+ return this.each(function() {
260
+ Selection.wrapSelectedText(this, beforeText, afterText, selectText);
261
+ });
262
+ }
263
+
264
+ });
265
+
266
+
267
+ })(jQuery);
@@ -0,0 +1,116 @@
1
+ (function($) {
2
+ var markups = {
3
+ creole: {
4
+ link: ['[[', 'link text', ']]'],
5
+ bold: ['**', 'bold text', '**'],
6
+ italic: ['//', 'italic text', '//'],
7
+ ul: ['* ', 'list item', '', true],
8
+ ol: ['# ', 'list item', '', true],
9
+ h1: ['= ', 'headline', '', true],
10
+ h2: ['== ', 'headline', '', true],
11
+ h3: ['=== ', 'headline', '', true],
12
+ sub: ['~~', 'subscript', '~~'],
13
+ sup: ['^^', 'superscript', '^^'],
14
+ del: ['--', 'deleted text', '--'],
15
+ ins: ['++', 'inserted text', '++'],
16
+ image: ['{{', 'image', '}}'],
17
+ preformatted: ['{{{', 'preformatted', '}}}']
18
+ },
19
+ markdown: {
20
+ link: function(selected) {
21
+ var target = prompt('link target:', selected);
22
+ return target ? ['[', 'link text', '](' + target + ')'] : null;
23
+ },
24
+ bold: ['**', 'bold text', '**'],
25
+ italic: ['*', 'italic text', '*'],
26
+ ul: ['* ', 'list item', '', true],
27
+ ol: ['1. ', 'list item', '', true],
28
+ h1: ['', 'headline', '\n========', true],
29
+ h2: ['', 'headline', '\n--------', true],
30
+ image: function(selected) {
31
+ var target = prompt('image path:', selected);
32
+ return target ? ['![', 'image alt text', '](' + target + ')'] : null;
33
+ },
34
+ preformatted: [' ', 'preformatted', '', true]
35
+ },
36
+ orgmode: {
37
+ bold: ['*', 'bold text', '*'],
38
+ italic: ['/', 'italic text', '/'],
39
+ ul: ['- ', 'list item', ''],
40
+ ol: ['1. ', 'list item', ''],
41
+ h1: ['* ', 'headline', ''],
42
+ h2: ['** ', 'headline', ''],
43
+ h3: ['*** ', 'headline', '']
44
+ },
45
+ textile: {
46
+ link: function(selected) {
47
+ var target = prompt('link target:', selected);
48
+ return target ? ['"', 'link text', '":' + target] : null;
49
+ },
50
+ bold: ['*', 'bold text', '*'],
51
+ italic: ['_', 'italic text', '_'],
52
+ ul: ['* ', 'list item', '', true],
53
+ ol: ['# ', 'list item', '', true],
54
+ h1: ['h1. ', 'headline', '', true],
55
+ h2: ['h2. ', 'headline', '', true],
56
+ h3: ['h3. ', 'headline', '', true],
57
+ em: ['_', 'emphasized text', '_'],
58
+ sub: ['~', 'subscript', '~'],
59
+ sup: ['^', 'superscript', '^'],
60
+ del: ['-', 'deleted text', '-'],
61
+ ins: ['+', 'inserted text', '+'],
62
+ image: ['!', 'image', '!']
63
+ }
64
+ };
65
+
66
+ function insertMarkup(textarea, config) {
67
+ var selected = textarea.getSelectedText();
68
+ if (typeof config == 'function') {
69
+ config = config(selected);
70
+ }
71
+ if (!config) {
72
+ return;
73
+ }
74
+ var range = textarea.getSelectionRange();
75
+ var prefix = config[0], content = config[1], suffix = config[2], newline = config[3];
76
+ if (newline) {
77
+ textarea.setSelectionRange(range.start - 1, range.start);
78
+ if (range.start !== 0 && textarea.getSelectedText() != '\n') {
79
+ prefix = '\n' + prefix;
80
+ }
81
+ textarea.setSelectionRange(range.end, range.end + 1);
82
+ if (textarea.getSelectedText() != '\n') {
83
+ suffix += '\n';
84
+ }
85
+ }
86
+ if (range.start == range.end) {
87
+ textarea.insertText(prefix + content + suffix, range.start, range.start, false);
88
+ textarea.setSelectionRange(range.start + prefix.length, range.start + prefix.length + content.length);
89
+ } else {
90
+ textarea.insertText(prefix + selected + suffix, range.start, range.end, false);
91
+ }
92
+ }
93
+
94
+ $.fn.markupEditor = function(markup) {
95
+ markup = markups[markup];
96
+ if (markup) {
97
+ var list = $('<ul class="button-bar" id="markup-editor"/>');
98
+
99
+ var buttons = [];
100
+ for (k in markup) {
101
+ buttons.push(k);
102
+ }
103
+ buttons.sort();
104
+ for (var i = 0; i < buttons.length; ++i) {
105
+ list.append('<li><a href="#" id="markup-editor-' + buttons[i] + '">' + buttons[i] + '</a></li>');
106
+ }
107
+ this.before(list);
108
+
109
+ var textarea = this;
110
+ $('a', list).click(function() {
111
+ insertMarkup(textarea, markup[this.id.substr(14)]);
112
+ return false;
113
+ });
114
+ }
115
+ };
116
+ })(jQuery);