olelo 0.9.6 → 0.9.7

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.
data/bin/olelo CHANGED
@@ -28,7 +28,7 @@ opts = OptionParser.new do |opts|
28
28
  options[:host] = host
29
29
  end
30
30
 
31
- opts.on('-s', '--server SERVER', 'serve using SERVER (webrick/mongrel)') do |server|
31
+ opts.on('-s', '--server SERVER', 'serve using SERVER (webrick/mongrel/thin)') do |server|
32
32
  options[:server] = server
33
33
  end
34
34
 
data/config.ru CHANGED
@@ -99,6 +99,7 @@ use Rack::MethodOverride
99
99
  use Rack::CommonLogger, LoggerOutput.new(logger)
100
100
  use Rack::RelativeRedirect
101
101
  use Olelo::Middleware::ForceEncoding
102
+ use Rack::Head
102
103
  run Olelo::Application.new
103
104
 
104
105
  logger.info "Olelo started in #{Olelo::Config['production'] ? 'production' : 'development'} mode"
@@ -21,6 +21,7 @@ production: true
21
21
  sidebar_page: 'Sidebar'
22
22
 
23
23
  # Use a different base directory as root to support installation in user homes
24
+ # e.g. /wiki
24
25
  base_path: '/'
25
26
 
26
27
  # Main cache store. Uncomment this!
@@ -13,7 +13,7 @@ module Olelo
13
13
 
14
14
  has_around_hooks :request, :routing, :action, :title, :footer, :login_buttons,
15
15
  :edit_buttons, :attributes_buttons, :upload_buttons
16
- has_hooks :auto_login, :render, :menu, :head, :script
16
+ has_hooks :auto_login, :render, :menu, :head
17
17
 
18
18
  def self.reserved_path?(path)
19
19
  path = '/' + path.cleanpath
@@ -32,7 +32,7 @@ module Olelo
32
32
  # Executed before each request
33
33
  before :routing do
34
34
  User.current = User.find(session[:olelo_user])
35
- if !User.current
35
+ unless User.current
36
36
  invoke_hook(:auto_login)
37
37
  User.current ||= User.anonymous(request)
38
38
  end
@@ -148,7 +148,7 @@ module Olelo
148
148
  raise NotFound
149
149
  end
150
150
  @version = @diff.to
151
- cache_control version: @version
151
+ cache_control etag: @version.to_s
152
152
  render :changes
153
153
  end
154
154
 
@@ -158,8 +158,7 @@ module Olelo
158
158
  @page_nr = [params[:page].to_i, 1].max
159
159
  @history = page.history((@page_nr - 1) * per_page, per_page)
160
160
  @page_count = @page_nr + @history.length / per_page
161
- @history = @history[0...per_page]
162
- cache_control version: page.version
161
+ cache_control etag: page.etag
163
162
  render :history
164
163
  end
165
164
 
@@ -269,7 +268,7 @@ module Olelo
269
268
  get '/(:path)', tail: true do
270
269
  begin
271
270
  @page = Page.find!(params[:path])
272
- cache_control version: page.version
271
+ cache_control etag: page.etag
273
272
  show_page
274
273
  rescue NotFound
275
274
  redirect build_path(params[:path], action: :new)
@@ -278,7 +277,7 @@ module Olelo
278
277
 
279
278
  get '/version/:version(/:path)' do
280
279
  @page = Page.find!(params[:path], params[:version])
281
- cache_control version: page.version
280
+ cache_control etag: page.etag
282
281
  show_page
283
282
  end
284
283
 
data/lib/olelo/helper.rb CHANGED
@@ -17,14 +17,6 @@ module Olelo
17
17
  def render_block(name)
18
18
  with_hooks(name) { yield }.join.html_safe
19
19
  end
20
-
21
- def include_or_define_block(name, content = nil, &block)
22
- if block_given? || content
23
- define_block(name, content, &block)
24
- else
25
- include_block(name)
26
- end
27
- end
28
20
  end
29
21
 
30
22
  module FlashHelper
@@ -242,11 +234,6 @@ module Olelo
242
234
  last_modified = last_modified.try(:to_time) || last_modified
243
235
  last_modified = last_modified.try(:httpdate) || last_modified
244
236
 
245
- if options[:version]
246
- options[:etag] = options[:version].cache_id
247
- options[:last_modified] = options[:version].date
248
- end
249
-
250
237
  if User.logged_in?
251
238
  # Always private mode if user is logged in
252
239
  options[:private] = true
@@ -309,31 +296,38 @@ module Olelo
309
296
  end
310
297
 
311
298
  def footer(content = nil, &block)
312
- include_or_define_block(:footer, content, &block)
299
+ if block_given? || content
300
+ define_block(:footer, content, &block)
301
+ else
302
+ include_block(:footer)
303
+ end
313
304
  end
314
305
 
315
306
  def title(content = nil, &block)
316
- include_or_define_block(:title, content, &block)
307
+ if block_given? || content
308
+ define_block(:title, content, &block)
309
+ else
310
+ include_block(:title)
311
+ end
317
312
  end
318
313
 
319
314
  def head
320
- @@theme_link ||=
315
+ @@js_css_links ||=
321
316
  begin
322
317
  file = File.join(Config['themes_path'], Config['theme'], 'style.css')
323
- path = build_path "static/themes/#{Config['theme']}/style.css?#{File.mtime(file).to_i}"
324
- %{<link rel="stylesheet" href="#{escape_html path}" type="text/css"/>}
325
- end
326
- @@script_link ||=
327
- begin
328
- path = build_path "static/script.js?#{File.mtime(File.join(Config['app_path'], 'static', 'script.js')).to_i}"
329
- %{<script src="#{escape_html path}" type="text/javascript"></script>}
318
+ css_path = build_path "static/themes/#{Config['theme']}/style.css?#{File.mtime(file).to_i}"
319
+ js_path = build_path "static/script.js?#{File.mtime(File.join(Config['app_path'], 'static', 'script.js')).to_i}"
320
+ %{<link rel="stylesheet" href="#{escape_html css_path}" type="text/css"/>
321
+ <script src="#{escape_html js_path}" type="text/javascript"></script>}
330
322
  end
323
+ # Add base path to root page to fix links in history browsing and for wikis with base_path
331
324
  base_path = if page && page.root?
332
325
  url = request.base_url
326
+ url << Config['base_path'] if Config['base_path'] != '/'
333
327
  url << '/' << 'version'/page.tree_version if !page.head?
334
328
  %{<base href="#{escape_html url}/"/>}.html_safe
335
329
  end
336
- [base_path, @@theme_link, @@script_link, *invoke_hook(:head)].join.html_safe
330
+ [base_path, @@js_css_links, *invoke_hook(:head)].join.html_safe
337
331
  end
338
332
 
339
333
  def session
@@ -1,3 +1,4 @@
1
+ # From ActionPack
1
2
  module Olelo
2
3
  module Middleware
3
4
  class UAHeader
data/lib/olelo/page.rb CHANGED
@@ -39,8 +39,8 @@ module Olelo
39
39
 
40
40
  attr_reader :path, :tree_version
41
41
 
42
- def initialize(path, tree_version = nil, parent = nil)
43
- @path, @tree_version, @parent = path.to_s.cleanpath.freeze, tree_version, parent
42
+ def initialize(path, tree_version = nil, etag = nil, parent = nil)
43
+ @path, @etag, @tree_version, @parent = path.to_s.cleanpath.freeze, etag, tree_version, parent
44
44
  Page.check_path(@path)
45
45
  end
46
46
 
@@ -67,7 +67,10 @@ module Olelo
67
67
  path = path.to_s.cleanpath
68
68
  check_path(path)
69
69
  tree_version = repository.get_version(tree_version) unless Version === tree_version
70
- Page.new(path, tree_version) if tree_version && repository.path_exists?(path, tree_version)
70
+ if tree_version
71
+ etag = repository.path_etag(path, tree_version)
72
+ Page.new(path, tree_version, etag) if etag
73
+ end
71
74
  end
72
75
 
73
76
  # Throws if not found
@@ -88,6 +91,13 @@ module Olelo
88
91
  mime.text? || mime == EMPTY_MIME || mime == DIRECTORY_MIME
89
92
  end
90
93
 
94
+ def etag
95
+ unless new?
96
+ @etag ||= repository.path_etag(path, tree_version)
97
+ "#{head? ? 1 : 0}-#{@etag}"
98
+ end
99
+ end
100
+
91
101
  def next_version
92
102
  init_versions
93
103
  @next_version
@@ -208,7 +218,7 @@ module Olelo
208
218
  []
209
219
  else
210
220
  repository.get_children(path, tree_version).sort.map do |name|
211
- Page.new(path/name, tree_version, self)
221
+ Page.new(path/name, tree_version, nil, self)
212
222
  end
213
223
  end
214
224
  end
@@ -41,10 +41,6 @@ module Olelo
41
41
  def ==(other)
42
42
  other.to_s == id
43
43
  end
44
-
45
- def cache_id
46
- "#{@id}-#{@head}"
47
- end
48
44
  end
49
45
 
50
46
  # Difference between versions
@@ -131,13 +127,13 @@ module Olelo
131
127
  raise NotImplementedError
132
128
  end
133
129
 
134
- # Check if path exists
130
+ # Check if path exists and return etag
135
131
  #
136
132
  # @param [String] path
137
133
  # @param [String, Version] version
138
- # @return [Boolean]
134
+ # @return [String]
139
135
  # @api public
140
- def path_exists?(path, version)
136
+ def path_etag(path, version)
141
137
  raise NotImplementedError
142
138
  end
143
139
 
data/lib/olelo/routing.rb CHANGED
@@ -32,8 +32,7 @@ module Olelo
32
32
 
33
33
  catch(:forward) do
34
34
  with_hooks(:request) { perform! }
35
- status, header, body = response.finish
36
- return [status, header, request.head? ? [] : body]
35
+ return response.finish
37
36
  end
38
37
 
39
38
  @app ? @app.call(env) : error!(NotFound.new(@request.path_info))
@@ -195,7 +194,6 @@ module Olelo
195
194
 
196
195
  def get(path, patterns = {}, &block)
197
196
  add_route('GET', path, patterns, &block)
198
- add_route('HEAD', path, patterns, &block)
199
197
  end
200
198
 
201
199
  def put(path, patterns = {}, &block)
data/lib/olelo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Olelo
2
- VERSION = '0.9.6'
2
+ VERSION = '0.9.7'
3
3
  end
@@ -146,7 +146,7 @@ end
146
146
  # Plug-in the aspect subsystem
147
147
  module ::Olelo::PageHelper
148
148
  def render_page(page)
149
- Cache.cache("include-#{page.path}-#{page.version.cache_id}", update: no_cache?, defer: true) do |context|
149
+ Cache.cache("include-#{page.path}-#{page.etag}", update: no_cache?, defer: true) do |context|
150
150
  begin
151
151
  context = Context.new(page: page, params: {included: true})
152
152
  Aspect.find!(page, layout: true).call(context, page)
@@ -162,7 +162,7 @@ class ::Olelo::Application
162
162
  def show_page
163
163
  params[:aspect] ||= 'subpages' if params[:path].to_s.ends_with? '/'
164
164
  @selected_aspect, layout, header, content =
165
- Cache.cache("aspect-#{page.path}-#{page.version.cache_id}-#{build_query(params)}",
165
+ Cache.cache("aspect-#{page.path}-#{page.etag}-#{build_query(params)}",
166
166
  update: no_cache?, defer: true) do |cache|
167
167
  aspect = Aspect.find!(page, name: params[:aspect])
168
168
  cache.disable! if !aspect.cacheable?
@@ -172,6 +172,7 @@ class ::Olelo::Application
172
172
  context.header['Content-Type'] ||= page.mime.to_s if !aspect.layout?
173
173
  [aspect.name, aspect.layout?, context.header.to_hash, result]
174
174
  end
175
+
175
176
  self.response.header.merge!(header)
176
177
 
177
178
  @menu_versions = true
@@ -186,18 +187,15 @@ class ::Olelo::Application
186
187
 
187
188
  hook :menu do |menu|
188
189
  if menu.name == :actions && view_menu = menu[:view]
189
- Cache.cache("aspect-menu-#{page.path}-#{page.version.cache_id}-#{@selected_aspect}",
190
- update: no_cache?, defer: true) do
191
- aspects = Aspect.find_all(page).select {|a| !a.hidden? || a.name == @selected_aspect || a.name == page.attributes['aspect'] }.map do |a|
192
- [Locale.translate("aspect_#{a.name}", fallback: titlecase(a.name)), a]
193
- end.sort_by(&:first)
194
- aspects.select {|label, a| a.layout? }.map do |label, a|
195
- MenuItem.new(a.name, label: label, href: build_path(page, aspect: a.name), class: a.name == @selected_aspect ? 'selected' : nil)
196
- end +
197
- aspects.reject {|label, a| a.layout? }.map do |label, a|
198
- MenuItem.new(a.name, label: label, href: build_path(page, aspect: a.name), class: 'download')
199
- end
200
- end.each {|item| view_menu << item }
190
+ aspects = Aspect.find_all(page).select {|a| !a.hidden? || a.name == @selected_aspect || a.name == page.attributes['aspect'] }.map do |a|
191
+ [Locale.translate("aspect_#{a.name}", fallback: titlecase(a.name)), a]
192
+ end.sort_by(&:first)
193
+ aspects.select {|label, a| a.layout? }.each do |label, a|
194
+ view_menu << MenuItem.new(a.name, label: label, href: build_path(page, aspect: a.name), class: a.name == @selected_aspect ? 'selected' : nil)
195
+ end
196
+ aspects.reject {|label, a| a.layout? }.each do |label, a|
197
+ view_menu << MenuItem.new(a.name, label: label, href: build_path(page, aspect: a.name), class: 'download')
198
+ end
201
199
  end
202
200
  end
203
201
  end
data/plugins/blog/main.rb CHANGED
@@ -10,7 +10,7 @@ end
10
10
  Tags::Tag.define 'menu', optional: 'path', description: 'Show blog menu', dynamic: true do |context, attrs, content|
11
11
  page = Page.find(attrs[:path]) rescue nil
12
12
  if page
13
- Cache.cache("blog-#{page.path}-#{page.version.cache_id}", update: no_cache?(context.request.env), defer: true) do
13
+ Cache.cache("blog-#{page.path}-#{page.etag}", update: no_cache?(context.request.env), defer: true) do
14
14
  years = {}
15
15
  page.children.each do |child|
16
16
  (years[child.version.date.year] ||= [])[child.version.date.month] = true
@@ -1,4 +1,6 @@
1
1
  $(function() {
2
+ "use strict";
3
+
2
4
  var textarea = $('#edit-content');
3
5
  if (textarea.length == 1) {
4
6
  textarea.hide().before('<div id="ace-editor" style="position:relative; width:100%; height: 40em"/>');
@@ -1,10 +1,10 @@
1
1
  (function(){var e=function(){var g=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(g){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
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(g){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,h){d=d||c;var i=c+b.length,l=a.value.substring(0,c);d=a.value.substr(d);a.value=l+b+d;h===true?this.setSelectionRange(a,c,i):this.setSelectionRange(a,i)},replaceSelectedText:function(a,b,c){var d=this.getSelectionRange(a);this.insertText(a,
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,h){d=d||c;var i=c+b.length,k=a.value.substring(0,c);d=a.value.substr(d);a.value=k+b+d;h===true?this.setSelectionRange(a,c,i):this.setSelectionRange(a,i)},replaceSelectedText:function(a,b,c){var d=this.getSelectionRange(a);this.insertText(a,
4
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=e})();
5
5
  (function(e){e.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(g,a){return this.each(function(){Selection.setSelectionRange(this,g,a)})},insertText:function(g,a,b,c){return this.each(function(){Selection.insertText(this,g,a,
6
6
  b,c)})},replaceSelectedText:function(g,a){return this.each(function(){Selection.replaceSelectedText(this,g,a)})},wrapSelectedText:function(g,a,b){return this.each(function(){Selection.wrapSelectedText(this,g,a,b)})}})})(jQuery);(function(e){var g={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
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
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","!"]}};e.fn.markupEditor=function(a){if(a=g[a]){var b=e('<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 h=this;e("a",b).click(function(){var i=a[this.id.substr(14)],l=h.getSelectedText();if(typeof i=="function")i=i(l);if(i){var f=h.getSelectionRange(),j=i[0],n=i[1],m=i[2];if(i[3]){h.setSelectionRange(f.start-1,f.start);if(f.start!==
10
- 0&&h.getSelectedText()!="\n")j="\n"+j;h.setSelectionRange(f.end,f.end+1);if(h.getSelectedText()!="\n")m+="\n"}if(f.start==f.end){h.insertText(j+n+m,f.start,f.start,false);h.setSelectionRange(f.start+j.length,f.start+j.length+n.length)}else h.insertText(j+l+m,f.start,f.end,false)}return false})}}})(jQuery);$(function(){var e=Olelo.page_mime;if(e=="application/x-empty"||e=="inode/directory")e=Olelo.default_mime;(e=/text\/x-(\w+)/.exec(e))&&$("#edit-content").markupEditor(e[1])});
9
+ image:["!","image","!"]}};e.fn.markupEditor=function(a){if(a=g[a]){var b=e('<ul class="button-bar" id="markup-editor"/>'),c=[];for(var d in a)c.push(d);c.sort();for(d=0;d<c.length;++d)b.append('<li><a href="#" id="markup-editor-'+c[d]+'">'+c[d]+"</a></li>");this.before(b);var h=this;e("a",b).click(function(){var i=a[this.id.substr(14)],k=h.getSelectedText();if(typeof i=="function")i=i(k);if(i){var f=h.getSelectionRange(),j=i[0],m=i[1],l=i[2];if(i[3]){h.setSelectionRange(f.start-1,f.start);if(f.start!==
10
+ 0&&h.getSelectedText()!="\n")j="\n"+j;h.setSelectionRange(f.end,f.end+1);if(h.getSelectedText()!="\n")l+="\n"}if(f.start==f.end){h.insertText(j+m+l,f.start,f.start,false);h.setSelectionRange(f.start+j.length,f.start+j.length+m.length)}else h.insertText(j+k+l,f.start,f.end,false)}return false})}}})(jQuery);$(function(){var e=Olelo.page_mime;if(e=="application/x-empty"||e=="inode/directory")e=Olelo.default_mime;(e=/text\/x-(\w+)/.exec(e))&&$("#edit-content").markupEditor(e[1])});
@@ -1,4 +1,6 @@
1
1
  (function($) {
2
+ "use strict";
3
+
2
4
  var markups = {
3
5
  creole: {
4
6
  link: ['[[', 'link text', ']]'],
@@ -97,7 +99,7 @@
97
99
  var list = $('<ul class="button-bar" id="markup-editor"/>');
98
100
 
99
101
  var buttons = [];
100
- for (k in markup) {
102
+ for (var k in markup) {
101
103
  buttons.push(k);
102
104
  }
103
105
  buttons.sort();
@@ -1,4 +1,6 @@
1
1
  $(function() {
2
+ "use strict";
3
+
2
4
  var mime = Olelo.page_mime;
3
5
  if (mime == 'application/x-empty' || mime == 'inode/directory') {
4
6
  mime = Olelo.default_mime;
@@ -1,15 +1,34 @@
1
1
  description 'Markdown nowiki filter'
2
2
 
3
+ # Embeds indented markdown text blocks in <notags> tags
4
+ # and adds <notags> around ``texts``
3
5
  Filter.create :markdown_nowiki do |context, content|
4
6
  output = ''
5
- until content.blank?
6
- case content
7
- when /(\A( {4}|\t).*)|(\A``.*?``)|(\A`[^`]*`)/
8
- output << "<notags>#{$&}</notags>"
9
- when /(\A[^`\n]+)|(\A\n+)/
10
- output << $&
7
+ block, state = nil, nil
8
+ content.each_line do |line|
9
+ if block
10
+ if line =~ /\A( {4}|\t)/
11
+ block << line
12
+ state = :in
13
+ elsif line =~ /\A\s*\Z/
14
+ block << line
15
+ state = :after if state == :in
16
+ elsif state == :after
17
+ output << "<notags>#{block}</notags>"
18
+ block = nil
19
+ else
20
+ block << line
21
+ line = block
22
+ block = nil
23
+ end
24
+ elsif line =~ /\A\s*\Z/
25
+ block, state = line, :before
26
+ end
27
+
28
+ unless block
29
+ output << line.gsub(/``.*?``|`[^`]*`/, '<notags>\0</notags>')
11
30
  end
12
- content = $'
13
31
  end
32
+ output << (state == :before ? block : "<notags>#{block}</notags>") if block
14
33
  output
15
34
  end
@@ -1,4 +1,6 @@
1
1
  $(function() {
2
+ "use strict";
3
+
2
4
  function initFancybox() {
3
5
  $('a.fancybox').each(function() {
4
6
  var href = this.href.replace(/aspect=\w+/g, '');
@@ -0,0 +1,30 @@
1
+ description 'Cache page fragments'
2
+ dependencies 'utils/cache'
3
+
4
+ class ::Olelo::Application
5
+ def cache_id
6
+ @cache_id ||= page ? "#{page.path}-#{page.etag}-#{build_query(params)}" : "#{request.path_info}-#{build_query(params)}"
7
+ end
8
+
9
+ redefine_method :menu do |name|
10
+ Cache.cache("menu-#{name}-#{cache_id}", update: no_cache?) do |cache|
11
+ super(name)
12
+ end
13
+ end
14
+
15
+ redefine_method :head do
16
+ Cache.cache("head-#{cache_id}", update: no_cache?) do |cache|
17
+ super()
18
+ end
19
+ end
20
+
21
+ redefine_method :footer do |content = nil, &block|
22
+ if block_given? || content
23
+ super(content, &block)
24
+ else
25
+ Cache.cache("footer-#{cache_id}", update: no_cache?) do |cache|
26
+ super()
27
+ end
28
+ end
29
+ end
30
+ end
@@ -24,9 +24,13 @@ class GitrbRepository < Repository
24
24
  end
25
25
 
26
26
  # @override
27
- def path_exists?(path, version)
27
+ def path_etag(path, version)
28
28
  check_path(path)
29
- !get_object(path, version).nil? rescue false
29
+ if id = get_object(path, version).id rescue nil
30
+ [id,
31
+ (get_object(path + CONTENT_EXT, version).id rescue nil),
32
+ (get_object(path + ATTRIBUTE_EXT, version).id rescue nil)].join('-')
33
+ end
30
34
  end
31
35
 
32
36
  # @override
@@ -73,7 +77,7 @@ class GitrbRepository < Repository
73
77
  if object
74
78
  content = object.data
75
79
  # Try to force utf-8 encoding and revert to old encoding if this doesn't work
76
- content.try_encoding(Encoding.default_encoding)
80
+ content.try_encoding(Encoding.default_external)
77
81
  else
78
82
  ''
79
83
  end
@@ -238,10 +238,14 @@ class RuggedRepository < Repository
238
238
  commit_to_version(@git.last_commit)
239
239
  end
240
240
 
241
- def path_exists?(path, version)
241
+ def path_etag(path, version)
242
242
  commit = @git.lookup(version.to_s)
243
243
  raise 'Not a commit' unless Rugged::Commit === commit
244
- path.blank? || commit.tree.path(path) != nil rescue nil
244
+ if oid = oid_by_path(commit, path)
245
+ [oid,
246
+ oid_by_path(commit, path + CONTENT_EXT),
247
+ oid_by_path(commit, path + ATTRIBUTE_EXT)].join('-')
248
+ end
245
249
  end
246
250
 
247
251
  def get_version(version = nil)
@@ -311,15 +315,17 @@ class RuggedRepository < Repository
311
315
  def get_children(path, version)
312
316
  commit = @git.lookup(version.to_s)
313
317
  raise 'Not a commit' unless Rugged::Commit === commit
314
- object = object_by_path(commit.tree, path)
315
- Rugged::Tree === object ? object.map {|e| e[:name].force_encoding(Encoding.default_external) }.reject {|name| reserved_name?(name) } : []
318
+ object = object_by_path(commit, path)
319
+ Rugged::Tree === object ? object.map do |e|
320
+ e[:name].force_encoding(Encoding.default_external)
321
+ end.reject {|name| reserved_name?(name) } : []
316
322
  end
317
323
 
318
324
  def get_content(path, version)
319
325
  commit = @git.lookup(version.to_s)
320
326
  raise 'Not a commit' unless Rugged::Commit === commit
321
- object = object_by_path(commit.tree, path)
322
- object = object_by_path(commit.tree, path + CONTENT_EXT) if Rugged::Tree === object
327
+ object = object_by_path(commit, path)
328
+ object = object_by_path(commit, path + CONTENT_EXT) if Rugged::Tree === object
323
329
  Rugged::Blob === object ? object.content.try_encoding(Encoding.default_external) : ''
324
330
  end
325
331
 
@@ -327,7 +333,7 @@ class RuggedRepository < Repository
327
333
  commit = @git.lookup(version.to_s)
328
334
  raise 'Not a commit' unless Rugged::Commit === commit
329
335
  path += ATTRIBUTE_EXT
330
- object = object_by_path(commit.tree, path)
336
+ object = object_by_path(commit, path)
331
337
  object ? YAML.load(object.content) : {}
332
338
  end
333
339
 
@@ -393,17 +399,23 @@ class RuggedRepository < Repository
393
399
  def path_changed?(c, path)
394
400
  return true if path.blank?
395
401
  ref1, ref2, ref3 = nil, nil, nil
396
- (c.parents.empty? && (ref1 ||= c.tree.path(path) rescue {})) || c.parents.any? do |parent|
397
- (ref1 ||= c.tree.path(path) rescue {}) != (parent.tree.path(path) rescue {}) ||
398
- (ref2 ||= c.tree.path(path + ATTRIBUTE_EXT) rescue {}) != (parent.tree.path(path + ATTRIBUTE_EXT) rescue {}) ||
399
- (ref3 ||= c.tree.path(path + CONTENT_EXT) rescue {}) != (parent.tree.path(path + CONTENT_EXT) rescue {})
402
+ (c.parents.empty? && (ref1 ||= oid_by_path(c, path))) || c.parents.any? do |parent|
403
+ (ref1 ||= oid_by_path(c, path)) != (oid_by_path(parent, path)) ||
404
+ (ref2 ||= oid_by_path(c, path + ATTRIBUTE_EXT)) != (oid_by_path(parent, path + ATTRIBUTE_EXT)) ||
405
+ (ref3 ||= oid_by_path(c, path + CONTENT_EXT)) != (oid_by_path(parent, path + CONTENT_EXT))
400
406
  end
401
407
  end
402
408
 
403
- def object_by_path(tree, path)
404
- return tree if path.blank?
405
- ref = tree.path(path)
406
- @git.lookup(ref[:oid])
409
+ def oid_by_path(commit, path)
410
+ return commit.tree_oid if path.blank?
411
+ commit.tree.path(path)[:oid]
412
+ rescue Rugged::IndexerError
413
+ nil
414
+ end
415
+
416
+ def object_by_path(commit, path)
417
+ return commit.tree if path.blank?
418
+ @git.lookup(commit.tree.path(path)[:oid])
407
419
  rescue Rugged::IndexerError
408
420
  nil
409
421
  end
@@ -1,6 +1,8 @@
1
1
  // Ajax Tree View
2
2
  // Written by Daniel Mendler, 2009
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  // Create treeview
5
7
  // $('div#id').treeView(...);
6
8
  $.fn.treeView = function(options) {
@@ -1,4 +1,6 @@
1
1
  $(function() {
2
+ "use strict";
3
+
2
4
  // Add treeview translations
3
5
  $.translations({
4
6
  en: {
@@ -1,6 +1,8 @@
1
1
  // Simple storage plugin
2
2
  // Written by Daniel Mendler
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  var storage = {}, data = {};
5
7
  try {
6
8
  if (window.localStorage) {
@@ -1,6 +1,8 @@
1
1
  // Very simple i18n plugin
2
2
  // Written by Daniel Mendler
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  var locale = null, translations = {};
5
7
  $.translations = function(t) {
6
8
  for (var lang in t) {
@@ -1,4 +1,6 @@
1
1
  (function($) {
2
+ "use strict";
3
+
2
4
  // Add treeview translations
3
5
  $.translations({
4
6
  en: {
@@ -1,4 +1,6 @@
1
1
  (function($) {
2
+ "use strict";
3
+
2
4
  $.fn.historyTable = function() {
3
5
  $('thead tr', this).prepend('<th class="compare"><button>&#177;</button></th>');
4
6
  $('tbody tr', this).each(function() {
@@ -3,6 +3,8 @@
3
3
  // $('#page_element').bind('pageLoaded', function() {});
4
4
  // Written by Daniel Mendler
5
5
  (function($) {
6
+ "use strict";
7
+
6
8
  $.fn.pagination = function(links) {
7
9
  var page = this;
8
10
 
@@ -1,6 +1,8 @@
1
1
  // Simple, unobtrusive tab widget
2
2
  // Written by Daniel Mendler
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  $.fn.tabWidget = function(options) {
5
7
  var store = options && options.store;
6
8
  var selected = null;
@@ -1,6 +1,8 @@
1
1
  // Replace timestamps with relative time
2
2
  // Written by Daniel Mendler
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  $.translations({
5
7
  en: {
6
8
  less_than_a_minute_ago: 'less than a minute ago',
@@ -1,6 +1,8 @@
1
1
  // Underline text in elements. Especially useful for accesskeys.
2
2
  // Written by Daniel Mendler
3
3
  (function($) {
4
+ "use strict";
5
+
4
6
  $.extend($.fn, {
5
7
  // Underline text
6
8
  underlineText: function(str) {
@@ -1,4 +1,6 @@
1
1
  (function($) {
2
+ "use strict";
3
+
2
4
  $.widget('ui.combobox', {
3
5
  _create: function() {
4
6
  var input = this.element;
@@ -1,6 +1,8 @@
1
1
  // Olelo bootstrap
2
2
  // Written by Daniel Mendler
3
3
  $(function() {
4
+ "use strict";
5
+
4
6
  $('html').removeClass('no-js').addClass('js');
5
7
  function pageLoaded() {
6
8
  $('#upload-path', this).each(function() {
data/test/request_test.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'helper'
2
2
  require 'olelo/middleware/force_encoding'
3
3
  require 'olelo/middleware/degrade_mime_type'
4
+ require 'olelo/middleware/ua_header'
4
5
  require 'rack/relative_redirect'
5
- require 'rack/session/pool'
6
6
 
7
7
  class Bacon::Context
8
8
  include Rack::Test::Methods
@@ -74,7 +74,9 @@ describe 'requests' do
74
74
  use Rack::MethodOverride
75
75
  use Olelo::Middleware::ForceEncoding
76
76
  use Olelo::Middleware::DegradeMimeType
77
+ use Olelo::Middleware::UAHeader
77
78
  #use Rack::RelativeRedirect
79
+ use Rack::Head
78
80
  run Olelo::Application.new
79
81
  end
80
82
  end
data/views/show.slim CHANGED
@@ -1,7 +1,7 @@
1
1
  - title page.title
2
- = define_block :version_link do
3
- a.version href=build_path(page, version: page.version, force_version: true) title=page.version = page.version.short
4
2
  = footer do
3
+ = define_block :version_link do
4
+ a.version href=build_path(page, version: page.version, force_version: true) title=page.version = page.version.short
5
5
  == :version_by.t(version: blocks[:version_link], author: escape_html(page.version.author.name), date: date(page.version.date))
6
6
  - if !page.attributes['no_title']
7
7
  h1= title
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: olelo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-05 00:00:00.000000000 Z
12
+ date: 2012-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &9838140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,15 +21,10 @@ dependencies:
21
21
  version: 1.3.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: 1.3.6
24
+ version_requirements: *9838140
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: slim
32
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &9836960 !ruby/object:Gem::Requirement
33
28
  none: false
34
29
  requirements:
35
30
  - - ~>
@@ -37,15 +32,10 @@ dependencies:
37
32
  version: 1.3.3
38
33
  type: :runtime
39
34
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.3.3
35
+ version_requirements: *9836960
46
36
  - !ruby/object:Gem::Dependency
47
37
  name: creole
48
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &9835660 !ruby/object:Gem::Requirement
49
39
  none: false
50
40
  requirements:
51
41
  - - ~>
@@ -53,15 +43,10 @@ dependencies:
53
43
  version: 0.5.0
54
44
  type: :runtime
55
45
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: 0.5.0
46
+ version_requirements: *9835660
62
47
  - !ruby/object:Gem::Dependency
63
48
  name: nokogiri
64
- requirement: !ruby/object:Gem::Requirement
49
+ requirement: &9833880 !ruby/object:Gem::Requirement
65
50
  none: false
66
51
  requirements:
67
52
  - - ~>
@@ -69,15 +54,10 @@ dependencies:
69
54
  version: 1.5.5
70
55
  type: :runtime
71
56
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 1.5.5
57
+ version_requirements: *9833880
78
58
  - !ruby/object:Gem::Dependency
79
59
  name: mimemagic
80
- requirement: !ruby/object:Gem::Requirement
60
+ requirement: &9832440 !ruby/object:Gem::Requirement
81
61
  none: false
82
62
  requirements:
83
63
  - - ~>
@@ -85,15 +65,10 @@ dependencies:
85
65
  version: 0.2.0
86
66
  type: :runtime
87
67
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 0.2.0
68
+ version_requirements: *9832440
94
69
  - !ruby/object:Gem::Dependency
95
70
  name: rack
96
- requirement: !ruby/object:Gem::Requirement
71
+ requirement: &9829740 !ruby/object:Gem::Requirement
97
72
  none: false
98
73
  requirements:
99
74
  - - ~>
@@ -101,15 +76,10 @@ dependencies:
101
76
  version: 1.4.1
102
77
  type: :runtime
103
78
  prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ~>
108
- - !ruby/object:Gem::Version
109
- version: 1.4.1
79
+ version_requirements: *9829740
110
80
  - !ruby/object:Gem::Dependency
111
81
  name: redcarpet
112
- requirement: !ruby/object:Gem::Requirement
82
+ requirement: &9829040 !ruby/object:Gem::Requirement
113
83
  none: false
114
84
  requirements:
115
85
  - - ~>
@@ -117,15 +87,10 @@ dependencies:
117
87
  version: 2.2.2
118
88
  type: :runtime
119
89
  prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ~>
124
- - !ruby/object:Gem::Version
125
- version: 2.2.2
90
+ version_requirements: *9829040
126
91
  - !ruby/object:Gem::Dependency
127
92
  name: rugged
128
- requirement: !ruby/object:Gem::Requirement
93
+ requirement: &9828020 !ruby/object:Gem::Requirement
129
94
  none: false
130
95
  requirements:
131
96
  - - ~>
@@ -133,15 +98,10 @@ dependencies:
133
98
  version: 0.17.0.b7
134
99
  type: :runtime
135
100
  prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ~>
140
- - !ruby/object:Gem::Version
141
- version: 0.17.0.b7
101
+ version_requirements: *9828020
142
102
  - !ruby/object:Gem::Dependency
143
103
  name: evaluator
144
- requirement: !ruby/object:Gem::Requirement
104
+ requirement: &9826260 !ruby/object:Gem::Requirement
145
105
  none: false
146
106
  requirements:
147
107
  - - ~>
@@ -149,15 +109,10 @@ dependencies:
149
109
  version: 0.1.6
150
110
  type: :runtime
151
111
  prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ~>
156
- - !ruby/object:Gem::Version
157
- version: 0.1.6
112
+ version_requirements: *9826260
158
113
  - !ruby/object:Gem::Dependency
159
114
  name: rake
160
- requirement: !ruby/object:Gem::Requirement
115
+ requirement: &9824340 !ruby/object:Gem::Requirement
161
116
  none: false
162
117
  requirements:
163
118
  - - ! '>='
@@ -165,15 +120,10 @@ dependencies:
165
120
  version: 0.8.7
166
121
  type: :development
167
122
  prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
- requirements:
171
- - - ! '>='
172
- - !ruby/object:Gem::Version
173
- version: 0.8.7
123
+ version_requirements: *9824340
174
124
  - !ruby/object:Gem::Dependency
175
125
  name: sass
176
- requirement: !ruby/object:Gem::Requirement
126
+ requirement: &9822920 !ruby/object:Gem::Requirement
177
127
  none: false
178
128
  requirements:
179
129
  - - ! '>='
@@ -181,15 +131,10 @@ dependencies:
181
131
  version: 3.1.0
182
132
  type: :development
183
133
  prerelease: false
184
- version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
- requirements:
187
- - - ! '>='
188
- - !ruby/object:Gem::Version
189
- version: 3.1.0
134
+ version_requirements: *9822920
190
135
  - !ruby/object:Gem::Dependency
191
136
  name: bacon
192
- requirement: !ruby/object:Gem::Requirement
137
+ requirement: &9822060 !ruby/object:Gem::Requirement
193
138
  none: false
194
139
  requirements:
195
140
  - - ~>
@@ -197,15 +142,10 @@ dependencies:
197
142
  version: 1.1.0
198
143
  type: :development
199
144
  prerelease: false
200
- version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
- requirements:
203
- - - ~>
204
- - !ruby/object:Gem::Version
205
- version: 1.1.0
145
+ version_requirements: *9822060
206
146
  - !ruby/object:Gem::Dependency
207
147
  name: rack-test
208
- requirement: !ruby/object:Gem::Requirement
148
+ requirement: &9812980 !ruby/object:Gem::Requirement
209
149
  none: false
210
150
  requirements:
211
151
  - - ~>
@@ -213,12 +153,7 @@ dependencies:
213
153
  version: 0.6.2
214
154
  type: :development
215
155
  prerelease: false
216
- version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
- requirements:
219
- - - ~>
220
- - !ruby/object:Gem::Version
221
- version: 0.6.2
156
+ version_requirements: *9812980
222
157
  description: Olelo is a git-based wiki which supports many markup languages, tags,
223
158
  embedded TeX and much more. It can be extended through plugins.
224
159
  email:
@@ -355,6 +290,7 @@ files:
355
290
  - plugins/misc/fancybox/script/01-jquery.easing.js
356
291
  - plugins/misc/fancybox/script/02-jquery.fancybox.js
357
292
  - plugins/misc/fancybox/script/init.js
293
+ - plugins/misc/fragment_cache.rb
358
294
  - plugins/misc/system.rb
359
295
  - plugins/misc/variables.rb
360
296
  - plugins/misc/webdav.rb
@@ -533,8 +469,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
533
469
  version: '0'
534
470
  requirements: []
535
471
  rubyforge_project: olelo
536
- rubygems_version: 1.8.23
472
+ rubygems_version: 1.8.15
537
473
  signing_key:
538
474
  specification_version: 3
539
475
  summary: Olelo is a git-based wiki.
540
476
  test_files: []
477
+ has_rdoc: