Converting linefeeds to Unix-style

This commit is contained in:
Alexey Verkhovsky 2006-03-19 21:49:53 +00:00
parent da24698a4c
commit d6fedc7f84
21 changed files with 5541 additions and 5541 deletions

View file

@ -1,32 +1,32 @@
class RevisionSweeper < ActionController::Caching::Sweeper class RevisionSweeper < ActionController::Caching::Sweeper
observe Revision, Page observe Revision, Page
def after_save(record) def after_save(record)
if record.is_a?(Revision) if record.is_a?(Revision)
expire_caches(record.page) expire_caches(record.page)
end end
end end
def after_delete(record) def after_delete(record)
if record.is_a?(Page) if record.is_a?(Page)
expire_caches(record) expire_caches(record)
end end
end end
private private
def expire_caches(page) def expire_caches(page)
web = page.web web = page.web
([page.name] + WikiReference.pages_that_reference(page.name)).uniq.each do |page_name| ([page.name] + WikiReference.pages_that_reference(page.name)).uniq.each do |page_name|
expire_action :controller => 'wiki', :web => web.address, expire_action :controller => 'wiki', :web => web.address,
:action => %w(show published), :id => page_name :action => %w(show published), :id => page_name
end end
expire_action :controller => 'wiki', :web => web.address, expire_action :controller => 'wiki', :web => web.address,
:action => %w(authors recently_revised list) :action => %w(authors recently_revised list)
expire_fragment :controller => 'wiki', :web => web.address, expire_fragment :controller => 'wiki', :web => web.address,
:action => %w(rss_with_headlines rss_with_content) :action => %w(rss_with_headlines rss_with_content)
end end
end end

View file

@ -1,15 +1,15 @@
# This class maintains the state of wiki references for newly created or newly deleted pages # This class maintains the state of wiki references for newly created or newly deleted pages
class PageObserver < ActiveRecord::Observer class PageObserver < ActiveRecord::Observer
def after_create(page) def after_create(page)
WikiReference.update_all("link_type = '#{WikiReference::LINKED_PAGE}'", WikiReference.update_all("link_type = '#{WikiReference::LINKED_PAGE}'",
['referenced_name = ?', page.name]) ['referenced_name = ?', page.name])
end end
def before_destroy(page) def before_destroy(page)
WikiReference.delete_all ['page_id = ?', page.id] WikiReference.delete_all ['page_id = ?', page.id]
WikiReference.update_all("link_type = '#{WikiReference::WANTED_PAGE}'", WikiReference.update_all("link_type = '#{WikiReference::WANTED_PAGE}'",
['referenced_name = ?', page.name]) ['referenced_name = ?', page.name])
end end
end end

View file

@ -1,64 +1,64 @@
class WikiFile < ActiveRecord::Base class WikiFile < ActiveRecord::Base
belongs_to :web belongs_to :web
before_save :write_content_to_file before_save :write_content_to_file
before_destroy :delete_content_file before_destroy :delete_content_file
validates_presence_of %w( web file_name ) validates_presence_of %w( web file_name )
validates_length_of :file_name, :within=>1..50 validates_length_of :file_name, :within=>1..50
validates_length_of :description, :maximum=>255 validates_length_of :description, :maximum=>255
def self.find_by_file_name(file_name) def self.find_by_file_name(file_name)
find(:first, :conditions => ['file_name = ?', file_name]) find(:first, :conditions => ['file_name = ?', file_name])
end end
SANE_FILE_NAME = /^[a-zA-Z0-9\-_\. ]*$/ SANE_FILE_NAME = /^[a-zA-Z0-9\-_\. ]*$/
def validate def validate
if file_name if file_name
if file_name !~ SANE_FILE_NAME if file_name !~ SANE_FILE_NAME
errors.add("file_name", "is invalid. Only latin characters, digits, dots, underscores, " + errors.add("file_name", "is invalid. Only latin characters, digits, dots, underscores, " +
"dashes and spaces are accepted") "dashes and spaces are accepted")
elsif file_name == '.' or file_name == '..' elsif file_name == '.' or file_name == '..'
errors.add("file_name", "cannot be '.' or '..'") errors.add("file_name", "cannot be '.' or '..'")
end end
end end
if @web and @content if @web and @content
if (@content.size > @web.max_upload_size.kilobytes) if (@content.size > @web.max_upload_size.kilobytes)
errors.add("content", "size (#{(@content.size / 1024.0).round} kilobytes) exceeds " + errors.add("content", "size (#{(@content.size / 1024.0).round} kilobytes) exceeds " +
"the maximum (#{web.max_upload_size} kilobytes) set for this wiki") "the maximum (#{web.max_upload_size} kilobytes) set for this wiki")
end end
end end
errors.add("content", "is empty") if @content.nil? or @content.empty? errors.add("content", "is empty") if @content.nil? or @content.empty?
end end
def content=(content) def content=(content)
if content.respond_to? :read if content.respond_to? :read
@content = content.read @content = content.read
else else
@content = content @content = content
end end
end end
def content def content
@content ||= ( File.open(content_path, 'rb') { |f| f.read } ) @content ||= ( File.open(content_path, 'rb') { |f| f.read } )
end end
def content_path def content_path
web.files_path + '/' + file_name web.files_path + '/' + file_name
end end
def write_content_to_file def write_content_to_file
web.create_files_directory unless File.exists?(web.files_path) web.create_files_directory unless File.exists?(web.files_path)
File.open(self.content_path, 'wb') { |f| f.write(@content) } File.open(self.content_path, 'wb') { |f| f.write(@content) }
end end
def delete_content_file def delete_content_file
require 'fileutils' require 'fileutils'
FileUtils.rm_f(content_path) if File.exists?(content_path) FileUtils.rm_f(content_path) if File.exists?(content_path)
end end
end end

View file

@ -1,82 +1,82 @@
class WikiReference < ActiveRecord::Base class WikiReference < ActiveRecord::Base
LINKED_PAGE = 'L' LINKED_PAGE = 'L'
WANTED_PAGE = 'W' WANTED_PAGE = 'W'
INCLUDED_PAGE = 'I' INCLUDED_PAGE = 'I'
CATEGORY = 'C' CATEGORY = 'C'
AUTHOR = 'A' AUTHOR = 'A'
FILE = 'F' FILE = 'F'
WANTED_FILE = 'E' WANTED_FILE = 'E'
belongs_to :page belongs_to :page
validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE] validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE]
# FIXME all finders below MUST restrict their results to pages belonging to a particular web # FIXME all finders below MUST restrict their results to pages belonging to a particular web
def self.link_type(web, page_name) def self.link_type(web, page_name)
web.has_page?(page_name) ? LINKED_PAGE : WANTED_PAGE web.has_page?(page_name) ? LINKED_PAGE : WANTED_PAGE
end end
def self.pages_that_reference(page_name) def self.pages_that_reference(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' + query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ?' + 'WHERE wiki_references.referenced_name = ?' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}', '#{INCLUDED_PAGE}')" "AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}', '#{INCLUDED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] } names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end end
def self.pages_that_link_to(page_name) def self.pages_that_link_to(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' + query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' + 'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}')" "AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] } names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end end
def self.pages_that_include(page_name) def self.pages_that_include(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' + query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' + 'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{INCLUDED_PAGE}'" "AND wiki_references.link_type = '#{INCLUDED_PAGE}'"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] } names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end end
def self.pages_in_category(category) def self.pages_in_category(category)
query = query =
'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' + 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' + 'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{CATEGORY}'" "AND wiki_references.link_type = '#{CATEGORY}'"
names = connection.select_all(sanitize_sql([query, category])).map { |row| row['name'] } names = connection.select_all(sanitize_sql([query, category])).map { |row| row['name'] }
end end
def self.list_categories def self.list_categories
query = "SELECT DISTINCT referenced_name FROM wiki_references WHERE link_type = '#{CATEGORY}'" query = "SELECT DISTINCT referenced_name FROM wiki_references WHERE link_type = '#{CATEGORY}'"
connection.select_all(query).map { |row| row['referenced_name'] } connection.select_all(query).map { |row| row['referenced_name'] }
end end
def wiki_word? def wiki_word?
linked_page? or wanted_page? linked_page? or wanted_page?
end end
def wiki_link? def wiki_link?
linked_page? or wanted_page? or file? or wanted_file? linked_page? or wanted_page? or file? or wanted_file?
end end
def linked_page? def linked_page?
link_type == LINKED_PAGE link_type == LINKED_PAGE
end end
def wanted_page? def wanted_page?
link_type == WANTED_PAGE link_type == WANTED_PAGE
end end
def included_page? def included_page?
link_type == INCLUDED_PAGE link_type == INCLUDED_PAGE
end end
def file? def file?
link_type == FILE link_type == FILE
end end
def wanted_file? def wanted_file?
link_type == WANTED_FILE link_type == WANTED_FILE
end end
end end

View file

@ -1,21 +1,21 @@
xml.rss('version' => '2.0') do xml.rss('version' => '2.0') do
xml.channel do xml.channel do
xml.title(@web.name) xml.title(@web.name)
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => 'HomePage')) xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => 'HomePage'))
xml.description('An Instiki wiki') xml.description('An Instiki wiki')
xml.language('en-us') xml.language('en-us')
xml.ttl('40') xml.ttl('40')
for page in @pages_by_revision for page in @pages_by_revision
xml.item do xml.item do
xml.title(page.plain_name) xml.title(page.plain_name)
unless @hide_description unless @hide_description
xml.description(rendered_content(page)) xml.description(rendered_content(page))
end end
xml.pubDate(page.revised_at.getgm.strftime('%a, %d %b %Y %H:%M:%S Z')) xml.pubDate(page.revised_at.getgm.strftime('%a, %d %b %Y %H:%M:%S Z'))
xml.guid(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name)) xml.guid(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name)) xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
end end
end end
end end
end end

View file

@ -1,17 +1,17 @@
unless defined?(RAILS_ROOT) unless defined?(RAILS_ROOT)
root_path = File.join(File.dirname(__FILE__), '..') root_path = File.join(File.dirname(__FILE__), '..')
unless RUBY_PLATFORM =~ /mswin32/ unless RUBY_PLATFORM =~ /mswin32/
require 'pathname' require 'pathname'
root_path = Pathname.new(root_path).cleanpath.to_s root_path = Pathname.new(root_path).cleanpath.to_s
end end
RAILS_ROOT = root_path RAILS_ROOT = root_path
end end
if File.directory?("#{RAILS_ROOT}/vendor/rails") if File.directory?("#{RAILS_ROOT}/vendor/rails")
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
else else
require 'rubygems' require 'rubygems'
require 'initializer' require 'initializer'
end end
Rails::Initializer.run(:set_load_path) Rails::Initializer.run(:set_load_path)

View file

@ -1,95 +1,95 @@
development: development:
adapter: mysql adapter: mysql
host: localhost host: localhost
database: instiki_dev database: instiki_dev
username: root username: root
password: password:
test: test:
adapter: mysql adapter: mysql
host: localhost host: localhost
database: instiki_test database: instiki_test
username: root username: root
password: password:
# "Out of the box", Instiki stores it's data in sqlite3 database. Other options are listed below. # "Out of the box", Instiki stores it's data in sqlite3 database. Other options are listed below.
production: production:
adapter: sqlite3 adapter: sqlite3
database: db/production.db.sqlite3 database: db/production.db.sqlite3
# MySQL (default setup). Versions 4.1 and 5.0 are recommended. # MySQL (default setup). Versions 4.1 and 5.0 are recommended.
# #
# Get the fast C bindings: # Get the fast C bindings:
# gem install mysql # gem install mysql
# (on OS X: gem install mysql -- --include=/usr/local/lib) # (on OS X: gem install mysql -- --include=/usr/local/lib)
# And be sure to use new-style password hashing: # And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html # http://dev.mysql.com/doc/refman/5.0/en/old-client.html
mysql_example: mysql_example:
adapter: mysql adapter: mysql
database: instiki_development database: instiki_development
username: root username: root
password: password:
socket: /path/to/your/mysql.sock socket: /path/to/your/mysql.sock
# Connect on a TCP socket. If omitted, the adapter will connect on the # Connect on a TCP socket. If omitted, the adapter will connect on the
# domain socket given by socket instead. # domain socket given by socket instead.
#host: localhost #host: localhost
#port: 3306 #port: 3306
# Warning: The database defined as 'test' will be erased and # Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'. # re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production. # Do not set this db to the same as development or production.
mysql_example: mysql_example:
adapter: mysql adapter: mysql
database: instiki_test database: instiki_test
username: root username: root
password: password:
socket: /path/to/your/mysql.sock socket: /path/to/your/mysql.sock
# PostgreSQL versions 7.4 - 8.1 # PostgreSQL versions 7.4 - 8.1
# #
# Get the C bindings: # Get the C bindings:
# gem install postgres # gem install postgres
# or use the pure-Ruby bindings on Windows: # or use the pure-Ruby bindings on Windows:
# gem install postgres-pr # gem install postgres-pr
postgresql_example: postgresql_example:
adapter: postgresql adapter: postgresql
database: instiki_development database: instiki_development
username: instiki username: instiki
password: password:
# Connect on a TCP socket. Omitted by default since the client uses a # Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. # domain socket that doesn't need configuration.
#host: remote-database #host: remote-database
#port: 5432 #port: 5432
# Schema search path. The server defaults to $user,public # Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public #schema_search_path: myapp,sharedapp,public
# Character set encoding. The server defaults to sql_ascii. # Character set encoding. The server defaults to sql_ascii.
#encoding: UTF8 #encoding: UTF8
# Minimum log levels, in increasing order: # Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1, # debug5, debug4, debug3, debug2, debug1,
# info, notice, warning, error, log, fatal, or panic # info, notice, warning, error, log, fatal, or panic
# The server defaults to notice. # The server defaults to notice.
#min_messages: warning #min_messages: warning
# SQLite version 2.x # SQLite version 2.x
# gem install sqlite-ruby # gem install sqlite-ruby
sqlite_example: sqlite_example:
adapter: sqlite adapter: sqlite
database: db/development.sqlite2 database: db/development.sqlite2
# SQLite version 3.x # SQLite version 3.x
# gem install sqlite3-ruby # gem install sqlite3-ruby
sqlite3_example: sqlite3_example:
adapter: sqlite3 adapter: sqlite3
database: db/development.sqlite3 database: db/development.sqlite3
# In-memory SQLite 3 database. Useful for tests. # In-memory SQLite 3 database. Useful for tests.
sqlite3_in_memory_example: sqlite3_in_memory_example:
adapter: sqlite3 adapter: sqlite3
database: ":memory:" database: ":memory:"

View file

@ -1,134 +1,134 @@
require 'diff' require 'diff'
# Temporary class containing all rendering stuff from a Revision # Temporary class containing all rendering stuff from a Revision
# I want to shift all rendering loguc to the controller eventually # I want to shift all rendering loguc to the controller eventually
class PageRenderer class PageRenderer
include HTMLDiff include HTMLDiff
def self.setup_url_generator(url_generator) def self.setup_url_generator(url_generator)
@@url_generator = url_generator @@url_generator = url_generator
end end
def self.teardown_url_generator def self.teardown_url_generator
@@url_generator = nil @@url_generator = nil
end end
attr_reader :revision attr_reader :revision
def initialize(revision = nil) def initialize(revision = nil)
self.revision = revision self.revision = revision
end end
def revision=(r) def revision=(r)
@revision = r @revision = r
@display_content = @display_published = @wiki_words_cache = @wiki_includes_cache = @display_content = @display_published = @wiki_words_cache = @wiki_includes_cache =
@wiki_references_cache = nil @wiki_references_cache = nil
end end
def display_content(update_references = false) def display_content(update_references = false)
@display_content ||= render(:update_references => update_references) @display_content ||= render(:update_references => update_references)
end end
def display_content_for_export def display_content_for_export
render :mode => :export render :mode => :export
end end
def display_published def display_published
@display_published ||= render(:mode => :publish) @display_published ||= render(:mode => :publish)
end end
def display_diff def display_diff
previous_revision = @revision.page.previous_revision(@revision) previous_revision = @revision.page.previous_revision(@revision)
if previous_revision if previous_revision
rendered_previous_revision = WikiContent.new(previous_revision, @@url_generator).render! rendered_previous_revision = WikiContent.new(previous_revision, @@url_generator).render!
diff(rendered_previous_revision, display_content) diff(rendered_previous_revision, display_content)
else else
display_content display_content
end end
end end
# Returns an array of all the WikiIncludes present in the content of this revision. # Returns an array of all the WikiIncludes present in the content of this revision.
def wiki_includes def wiki_includes
unless @wiki_includes_cache unless @wiki_includes_cache
chunks = display_content.find_chunks(Include) chunks = display_content.find_chunks(Include)
@wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq @wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end end
@wiki_includes_cache @wiki_includes_cache
end end
# Returns an array of all the WikiReferences present in the content of this revision. # Returns an array of all the WikiReferences present in the content of this revision.
def wiki_references def wiki_references
unless @wiki_references_cache unless @wiki_references_cache
chunks = display_content.find_chunks(WikiChunk::WikiReference) chunks = display_content.find_chunks(WikiChunk::WikiReference)
@wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq @wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end end
@wiki_references_cache @wiki_references_cache
end end
# Returns an array of all the WikiWords present in the content of this revision. # Returns an array of all the WikiWords present in the content of this revision.
def wiki_words def wiki_words
@wiki_words_cache ||= find_wiki_words(display_content) @wiki_words_cache ||= find_wiki_words(display_content)
end end
def find_wiki_words(rendering_result) def find_wiki_words(rendering_result)
wiki_links = rendering_result.find_chunks(WikiChunk::WikiLink) wiki_links = rendering_result.find_chunks(WikiChunk::WikiLink)
# Exclude backslash-escaped wiki words, such as \WikiWord, as well as links to files # Exclude backslash-escaped wiki words, such as \WikiWord, as well as links to files
# and pictures, such as [[foo.txt:file]] or [[foo.jpg:pic]] # and pictures, such as [[foo.txt:file]] or [[foo.jpg:pic]]
wiki_links.delete_if { |link| link.escaped? or [:pic, :file].include?(link.link_type) } wiki_links.delete_if { |link| link.escaped? or [:pic, :file].include?(link.link_type) }
# convert to the list of unique page names # convert to the list of unique page names
wiki_links.map { |link| ( link.page_name ) }.uniq wiki_links.map { |link| ( link.page_name ) }.uniq
end end
# Returns an array of all the WikiWords present in the content of this revision. # Returns an array of all the WikiWords present in the content of this revision.
# that already exists as a page in the web. # that already exists as a page in the web.
def existing_pages def existing_pages
wiki_words.select { |wiki_word| @revision.page.web.page(wiki_word) } wiki_words.select { |wiki_word| @revision.page.web.page(wiki_word) }
end end
# Returns an array of all the WikiWords present in the content of this revision # Returns an array of all the WikiWords present in the content of this revision
# that *doesn't* already exists as a page in the web. # that *doesn't* already exists as a page in the web.
def unexisting_pages def unexisting_pages
wiki_words - existing_pages wiki_words - existing_pages
end end
private private
def render(options = {}) def render(options = {})
rendering_result = WikiContent.new(@revision, @@url_generator, options).render! rendering_result = WikiContent.new(@revision, @@url_generator, options).render!
update_references(rendering_result) if options[:update_references] update_references(rendering_result) if options[:update_references]
rendering_result rendering_result
end end
def update_references(rendering_result) def update_references(rendering_result)
WikiReference.delete_all ['page_id = ?', @revision.page_id] WikiReference.delete_all ['page_id = ?', @revision.page_id]
references = @revision.page.wiki_references references = @revision.page.wiki_references
wiki_words = find_wiki_words(rendering_result) wiki_words = find_wiki_words(rendering_result)
# TODO it may be desirable to save links to files and pictures as WikiReference objects # TODO it may be desirable to save links to files and pictures as WikiReference objects
# present version doesn't do it # present version doesn't do it
wiki_words.each do |referenced_name| wiki_words.each do |referenced_name|
# Links to self are always considered linked # Links to self are always considered linked
if referenced_name == @revision.page.name if referenced_name == @revision.page.name
link_type = WikiReference::LINKED_PAGE link_type = WikiReference::LINKED_PAGE
else else
link_type = WikiReference.link_type(@revision.page.web, referenced_name) link_type = WikiReference.link_type(@revision.page.web, referenced_name)
end end
references.create :referenced_name => referenced_name, :link_type => link_type references.create :referenced_name => referenced_name, :link_type => link_type
end end
include_chunks = rendering_result.find_chunks(Include) include_chunks = rendering_result.find_chunks(Include)
includes = include_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq includes = include_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
includes.each do |included_page_name| includes.each do |included_page_name|
references.create :referenced_name => included_page_name, references.create :referenced_name => included_page_name,
:link_type => WikiReference::INCLUDED_PAGE :link_type => WikiReference::INCLUDED_PAGE
end end
categories = rendering_result.find_chunks(Category).map { |cat| cat.list }.flatten categories = rendering_result.find_chunks(Category).map { |cat| cat.list }.flatten
categories.each do |category| categories.each do |category|
references.create :referenced_name => category, :link_type => WikiReference::CATEGORY references.create :referenced_name => category, :link_type => WikiReference::CATEGORY
end end
end end
end end

View file

@ -1,121 +1,121 @@
class AbstractUrlGenerator class AbstractUrlGenerator
def initialize(controller) def initialize(controller)
raise 'Controller cannot be nil' if controller.nil? raise 'Controller cannot be nil' if controller.nil?
@controller = controller @controller = controller
end end
# Create a link for the given page (or file) name and link text based # Create a link for the given page (or file) name and link text based
# on the render mode in options and whether the page (file) exists # on the render mode in options and whether the page (file) exists
# in the web. # in the web.
def make_link(name, web, text = nil, options = {}) def make_link(name, web, text = nil, options = {})
text = CGI.escapeHTML(text || WikiWords.separate(name)) text = CGI.escapeHTML(text || WikiWords.separate(name))
mode = (options[:mode] || :show).to_sym mode = (options[:mode] || :show).to_sym
link_type = (options[:link_type] || :show).to_sym link_type = (options[:link_type] || :show).to_sym
if (link_type == :show) if (link_type == :show)
known_page = web.has_page?(name) known_page = web.has_page?(name)
else else
known_page = web.has_file?(name) known_page = web.has_file?(name)
end end
case link_type case link_type
when :show when :show
page_link(mode, name, text, web.address, known_page) page_link(mode, name, text, web.address, known_page)
when :file when :file
file_link(mode, name, text, web.address, known_page) file_link(mode, name, text, web.address, known_page)
when :pic when :pic
pic_link(mode, name, text, web.address, known_page) pic_link(mode, name, text, web.address, known_page)
else else
raise "Unknown link type: #{link_type}" raise "Unknown link type: #{link_type}"
end end
end end
end end
class UrlGenerator < AbstractUrlGenerator class UrlGenerator < AbstractUrlGenerator
private private
def file_link(mode, name, text, web_address, known_file) def file_link(mode, name, text, web_address, known_file)
case mode case mode
when :export when :export
if known_file if known_file
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>} %{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else else
%{<span class="newWikiWord">#{text}</span>} %{<span class="newWikiWord">#{text}</span>}
end end
when :publish when :publish
if known_file if known_file
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file', href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name :id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>} %{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else else
%{<span class="newWikiWord">#{text}</span>} %{<span class="newWikiWord">#{text}</span>}
end end
else else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file', href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name :id => name
if known_file if known_file
%{<a class="existingWikiWord" href="#{href}">#{text}</a>} %{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>} %{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end end
end end
end end
def page_link(mode, name, text, web_address, known_page) def page_link(mode, name, text, web_address, known_page)
case mode case mode
when :export when :export
if known_page if known_page
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>} %{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else else
%{<span class="newWikiWord">#{text}</span>} %{<span class="newWikiWord">#{text}</span>}
end end
when :publish when :publish
if known_page if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published', href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published',
:id => name :id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>} %{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else else
%{<span class="newWikiWord">#{text}</span>} %{<span class="newWikiWord">#{text}</span>}
end end
else else
if known_page if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'show', href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'show',
:id => name :id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>} %{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else else
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'new', href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'new',
:id => name :id => name
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>} %{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end end
end end
end end
def pic_link(mode, name, text, web_address, known_pic) def pic_link(mode, name, text, web_address, known_pic)
case mode case mode
when :export when :export
if known_pic if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />} %{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else else
%{<img alt="#{text}" src="no image" />} %{<img alt="#{text}" src="no image" />}
end end
when :publish when :publish
if known_pic if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />} %{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else else
%{<span class="newWikiWord">#{text}</span>} %{<span class="newWikiWord">#{text}</span>}
end end
else else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file', href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name :id => name
if known_pic if known_pic
%{<img alt="#{text}" src="#{href}" />} %{<img alt="#{text}" src="#{href}" />}
else else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>} %{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end end
end end
end end
end end

View file

@ -1,10 +1,10 @@
#!c:/ruby/bin/ruby #!c:/ruby/bin/ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
require "dispatcher" require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
Dispatcher.dispatch Dispatcher.dispatch

View file

@ -1,24 +1,24 @@
#!c:/ruby/bin/ruby #!c:/ruby/bin/ruby
# #
# You may specify the path to the FastCGI crash log (a log of unhandled # You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging) # exceptions which forced the FastCGI instance to exit, great for debugging)
# and the number of requests to process before running garbage collection. # and the number of requests to process before running garbage collection.
# #
# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log # By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
# and the GC period is nil (turned off). A reasonable number of requests # and the GC period is nil (turned off). A reasonable number of requests
# could range from 10-100 depending on the memory footprint of your app. # could range from 10-100 depending on the memory footprint of your app.
# #
# Example: # Example:
# # Default log path, normal GC behavior. # # Default log path, normal GC behavior.
# RailsFCGIHandler.process! # RailsFCGIHandler.process!
# #
# # Default log path, 50 requests between GC. # # Default log path, 50 requests between GC.
# RailsFCGIHandler.process! nil, 50 # RailsFCGIHandler.process! nil, 50
# #
# # Custom log path, normal GC behavior. # # Custom log path, normal GC behavior.
# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' # RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
# #
require File.dirname(__FILE__) + "/../config/environment" require File.dirname(__FILE__) + "/../config/environment"
require 'fcgi_handler' require 'fcgi_handler'
RailsFCGIHandler.process! RailsFCGIHandler.process!

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,47 +1,47 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the // a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including // "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish, // without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to // distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to // permit persons to whom the Software is furnished to do so, subject to
// the following conditions: // the following conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var Scriptaculous = { var Scriptaculous = {
Version: '1.5_rc3', Version: '1.5_rc3',
require: function(libraryName) { require: function(libraryName) {
// inserting via DOM fails in Safari 2.0, so brute force approach // inserting via DOM fails in Safari 2.0, so brute force approach
document.write('<script type="text/javascript" src="'+libraryName+'"></script>'); document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
}, },
load: function() { load: function() {
if((typeof Prototype=='undefined') || if((typeof Prototype=='undefined') ||
parseFloat(Prototype.Version.split(".")[0] + "." + parseFloat(Prototype.Version.split(".")[0] + "." +
Prototype.Version.split(".")[1]) < 1.4) Prototype.Version.split(".")[1]) < 1.4)
throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0"); throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
var scriptTags = document.getElementsByTagName("script"); var scriptTags = document.getElementsByTagName("script");
for(var i=0;i<scriptTags.length;i++) { for(var i=0;i<scriptTags.length;i++) {
if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) { if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) {
var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,''); var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,'');
this.require(path + 'effects.js'); this.require(path + 'effects.js');
this.require(path + 'dragdrop.js'); this.require(path + 'dragdrop.js');
this.require(path + 'controls.js'); this.require(path + 'controls.js');
this.require(path + 'slider.js'); this.require(path + 'slider.js');
break; break;
} }
} }
} }
} }
Scriptaculous.load(); Scriptaculous.load();

View file

@ -1,258 +1,258 @@
// Copyright (c) 2005 Marty Haught // Copyright (c) 2005 Marty Haught
// //
// See scriptaculous.js for full license. // See scriptaculous.js for full license.
if(!Control) var Control = {}; if(!Control) var Control = {};
Control.Slider = Class.create(); Control.Slider = Class.create();
// options: // options:
// axis: 'vertical', or 'horizontal' (default) // axis: 'vertical', or 'horizontal' (default)
// increment: (default: 1) // increment: (default: 1)
// step: (default: 1) // step: (default: 1)
// //
// callbacks: // callbacks:
// onChange(value) // onChange(value)
// onSlide(value) // onSlide(value)
Control.Slider.prototype = { Control.Slider.prototype = {
initialize: function(handle, track, options) { initialize: function(handle, track, options) {
this.handle = $(handle); this.handle = $(handle);
this.track = $(track); this.track = $(track);
this.options = options || {}; this.options = options || {};
this.axis = this.options.axis || 'horizontal'; this.axis = this.options.axis || 'horizontal';
this.increment = this.options.increment || 1; this.increment = this.options.increment || 1;
this.step = parseInt(this.options.step) || 1; this.step = parseInt(this.options.step) || 1;
this.value = 0; this.value = 0;
var defaultMaximum = Math.round(this.track.offsetWidth / this.increment); var defaultMaximum = Math.round(this.track.offsetWidth / this.increment);
if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment); if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment);
this.maximum = this.options.maximum || defaultMaximum; this.maximum = this.options.maximum || defaultMaximum;
this.minimum = this.options.minimum || 0; this.minimum = this.options.minimum || 0;
// Will be used to align the handle onto the track, if necessary // Will be used to align the handle onto the track, if necessary
this.alignX = parseInt (this.options.alignX) || 0; this.alignX = parseInt (this.options.alignX) || 0;
this.alignY = parseInt (this.options.alignY) || 0; this.alignY = parseInt (this.options.alignY) || 0;
// Zero out the slider position // Zero out the slider position
this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX); this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX);
this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY); this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY);
this.offsetX = 0; this.offsetX = 0;
this.offsetY = 0; this.offsetY = 0;
this.originalLeft = this.currentLeft(); this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop(); this.originalTop = this.currentTop();
this.originalZ = parseInt(this.handle.style.zIndex || "0"); this.originalZ = parseInt(this.handle.style.zIndex || "0");
// Prepopulate Slider value // Prepopulate Slider value
this.setSliderValue(parseInt(this.options.sliderValue) || 0); this.setSliderValue(parseInt(this.options.sliderValue) || 0);
this.active = false; this.active = false;
this.dragging = false; this.dragging = false;
this.disabled = false; this.disabled = false;
// FIXME: use css // FIXME: use css
this.handleImage = $(this.options.handleImage) || false; this.handleImage = $(this.options.handleImage) || false;
this.handleDisabled = this.options.handleDisabled || false; this.handleDisabled = this.options.handleDisabled || false;
this.handleEnabled = false; this.handleEnabled = false;
if(this.handleImage) if(this.handleImage)
this.handleEnabled = this.handleImage.src || false; this.handleEnabled = this.handleImage.src || false;
if(this.options.disabled) if(this.options.disabled)
this.setDisabled(); this.setDisabled();
// Value Array // Value Array
this.values = this.options.values || false; // Add method to validate and sort?? this.values = this.options.values || false; // Add method to validate and sort??
Element.makePositioned(this.handle); // fix IE Element.makePositioned(this.handle); // fix IE
this.eventMouseDown = this.startDrag.bindAsEventListener(this); this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this); this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this); this.eventMouseMove = this.update.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this); this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown); Event.observe(this.handle, "mousedown", this.eventMouseDown);
Event.observe(document, "mouseup", this.eventMouseUp); Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove); Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress); Event.observe(document, "keypress", this.eventKeypress);
}, },
dispose: function() { dispose: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Event.stopObserving(document, "mouseup", this.eventMouseUp); Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove); Event.stopObserving(document, "mousemove", this.eventMouseMove);
Event.stopObserving(document, "keypress", this.eventKeypress); Event.stopObserving(document, "keypress", this.eventKeypress);
}, },
setDisabled: function(){ setDisabled: function(){
this.disabled = true; this.disabled = true;
if(this.handleDisabled) if(this.handleDisabled)
this.handleImage.src = this.handleDisabled; this.handleImage.src = this.handleDisabled;
}, },
setEnabled: function(){ setEnabled: function(){
this.disabled = false; this.disabled = false;
if(this.handleEnabled) if(this.handleEnabled)
this.handleImage.src = this.handleEnabled; this.handleImage.src = this.handleEnabled;
}, },
currentLeft: function() { currentLeft: function() {
return parseInt(this.handle.style.left || '0'); return parseInt(this.handle.style.left || '0');
}, },
currentTop: function() { currentTop: function() {
return parseInt(this.handle.style.top || '0'); return parseInt(this.handle.style.top || '0');
}, },
setCurrentLeft: function(left) { setCurrentLeft: function(left) {
this.handle.style.left = left +"px"; this.handle.style.left = left +"px";
}, },
setCurrentTop: function(top) { setCurrentTop: function(top) {
this.handle.style.top = top +"px"; this.handle.style.top = top +"px";
}, },
trackLeft: function(){ trackLeft: function(){
return Position.cumulativeOffset(this.track)[0]; return Position.cumulativeOffset(this.track)[0];
}, },
trackTop: function(){ trackTop: function(){
return Position.cumulativeOffset(this.track)[1]; return Position.cumulativeOffset(this.track)[1];
}, },
getNearestValue: function(value){ getNearestValue: function(value){
if(this.values){ if(this.values){
var i = 0; var i = 0;
var offset = Math.abs(this.values[0] - value); var offset = Math.abs(this.values[0] - value);
var newValue = this.values[0]; var newValue = this.values[0];
for(i=0; i < this.values.length; i++){ for(i=0; i < this.values.length; i++){
var currentOffset = Math.abs(this.values[i] - value); var currentOffset = Math.abs(this.values[i] - value);
if(currentOffset < offset){ if(currentOffset < offset){
newValue = this.values[i]; newValue = this.values[i];
offset = currentOffset; offset = currentOffset;
} }
} }
return newValue; return newValue;
} }
return value; return value;
}, },
setSliderValue: function(sliderValue){ setSliderValue: function(sliderValue){
// First check our max and minimum and nearest values // First check our max and minimum and nearest values
sliderValue = this.getNearestValue(sliderValue); sliderValue = this.getNearestValue(sliderValue);
if(sliderValue > this.maximum) sliderValue = this.maximum; if(sliderValue > this.maximum) sliderValue = this.maximum;
if(sliderValue < this.minimum) sliderValue = this.minimum; if(sliderValue < this.minimum) sliderValue = this.minimum;
var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment; var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment;
if(this.isVertical()){ if(this.isVertical()){
this.setCurrentTop(offsetDiff + this.currentTop()); this.setCurrentTop(offsetDiff + this.currentTop());
} else { } else {
this.setCurrentLeft(offsetDiff + this.currentLeft()); this.setCurrentLeft(offsetDiff + this.currentLeft());
} }
this.value = sliderValue; this.value = sliderValue;
this.updateFinished(); this.updateFinished();
}, },
minimumOffset: function(){ minimumOffset: function(){
return(this.isVertical() ? return(this.isVertical() ?
this.trackTop() + this.alignY : this.trackTop() + this.alignY :
this.trackLeft() + this.alignX); this.trackLeft() + this.alignX);
}, },
maximumOffset: function(){ maximumOffset: function(){
return(this.isVertical() ? return(this.isVertical() ?
this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment : this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment :
this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment); this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment);
}, },
isVertical: function(){ isVertical: function(){
return (this.axis == 'vertical'); return (this.axis == 'vertical');
}, },
startDrag: function(event) { startDrag: function(event) {
if(Event.isLeftClick(event)) { if(Event.isLeftClick(event)) {
if(!this.disabled){ if(!this.disabled){
this.active = true; this.active = true;
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle); var offsets = Position.cumulativeOffset(this.handle);
this.offsetX = (pointer[0] - offsets[0]); this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]); this.offsetY = (pointer[1] - offsets[1]);
this.originalLeft = this.currentLeft(); this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop(); this.originalTop = this.currentTop();
} }
Event.stop(event); Event.stop(event);
} }
}, },
update: function(event) { update: function(event) {
if(this.active) { if(this.active) {
if(!this.dragging) { if(!this.dragging) {
var style = this.handle.style; var style = this.handle.style;
this.dragging = true; this.dragging = true;
if(style.position=="") style.position = "relative"; if(style.position=="") style.position = "relative";
style.zIndex = this.options.zindex; style.zIndex = this.options.zindex;
} }
this.draw(event); this.draw(event);
// fix AppleWebKit rendering // fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
Event.stop(event); Event.stop(event);
} }
}, },
draw: function(event) { draw: function(event) {
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle); var offsets = Position.cumulativeOffset(this.handle);
offsets[0] -= this.currentLeft(); offsets[0] -= this.currentLeft();
offsets[1] -= this.currentTop(); offsets[1] -= this.currentTop();
// Adjust for the pointer's position on the handle // Adjust for the pointer's position on the handle
pointer[0] -= this.offsetX; pointer[0] -= this.offsetX;
pointer[1] -= this.offsetY; pointer[1] -= this.offsetY;
var style = this.handle.style; var style = this.handle.style;
if(this.isVertical()){ if(this.isVertical()){
if(pointer[1] > this.maximumOffset()) if(pointer[1] > this.maximumOffset())
pointer[1] = this.maximumOffset(); pointer[1] = this.maximumOffset();
if(pointer[1] < this.minimumOffset()) if(pointer[1] < this.minimumOffset())
pointer[1] = this.minimumOffset(); pointer[1] = this.minimumOffset();
// Increment by values // Increment by values
if(this.values){ if(this.values){
this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum); this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment; pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment;
} else { } else {
this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum; this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum;
} }
style.top = pointer[1] - offsets[1] + "px"; style.top = pointer[1] - offsets[1] + "px";
} else { } else {
if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset(); if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset();
if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset(); if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset();
// Increment by values // Increment by values
if(this.values){ if(this.values){
this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum); this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment; pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment;
} else { } else {
this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum; this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum;
} }
style.left = (pointer[0] - offsets[0]) + "px"; style.left = (pointer[0] - offsets[0]) + "px";
} }
if(this.options.onSlide) this.options.onSlide(this.value); if(this.options.onSlide) this.options.onSlide(this.value);
}, },
endDrag: function(event) { endDrag: function(event) {
if(this.active && this.dragging) { if(this.active && this.dragging) {
this.finishDrag(event, true); this.finishDrag(event, true);
Event.stop(event); Event.stop(event);
} }
this.active = false; this.active = false;
this.dragging = false; this.dragging = false;
}, },
finishDrag: function(event, success) { finishDrag: function(event, success) {
this.active = false; this.active = false;
this.dragging = false; this.dragging = false;
this.handle.style.zIndex = this.originalZ; this.handle.style.zIndex = this.originalZ;
this.originalLeft = this.currentLeft(); this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop(); this.originalTop = this.currentTop();
this.updateFinished(); this.updateFinished();
}, },
updateFinished: function() { updateFinished: function() {
if(this.options.onChange) this.options.onChange(this.value); if(this.options.onChange) this.options.onChange(this.value);
}, },
keyPress: function(event) { keyPress: function(event) {
if(this.active && !this.disabled) { if(this.active && !this.disabled) {
switch(event.keyCode) { switch(event.keyCode) {
case Event.KEY_ESC: case Event.KEY_ESC:
this.finishDrag(event, false); this.finishDrag(event, false);
Event.stop(event); Event.stop(event);
break; break;
} }
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
} }
} }
} }

View file

@ -1,10 +1,10 @@
# Add your own tasks in files placed in lib/tasks ending in .rake, # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake. # for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
require(File.join(File.dirname(__FILE__), 'config', 'boot')) require(File.join(File.dirname(__FILE__), 'config', 'boot'))
require 'rake' require 'rake'
require 'rake/testtask' require 'rake/testtask'
require 'rake/rdoctask' require 'rake/rdoctask'
require 'tasks/rails' require 'tasks/rails'

View file

@ -1,112 +1,112 @@
my_way_1: my_way_1:
id: 1 id: 1
page_id: 2 page_id: 2
referenced_name: MyWay referenced_name: MyWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
smart_engine_1: smart_engine_1:
id: 2 id: 2
page_id: 3 page_id: 3
referenced_name: SmartEngine referenced_name: SmartEngine
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
that_way_1: that_way_1:
id: 3 id: 3
page_id: 4 page_id: 4
referenced_name: ThatWay referenced_name: ThatWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_1: home_page_1:
id: 4 id: 4
page_id: 1 page_id: 1
referenced_name: HisWay referenced_name: HisWay
link_type: W link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_2: home_page_2:
id: 5 id: 5
page_id: 1 page_id: 1
referenced_name: MyWay referenced_name: MyWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_3: home_page_3:
id: 6 id: 6
page_id: 1 page_id: 1
referenced_name: ThatWay referenced_name: ThatWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_4: home_page_4:
id: 7 id: 7
page_id: 1 page_id: 1
referenced_name: SmartEngine referenced_name: SmartEngine
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_1: first_page_1:
id: 8 id: 8
page_id: 6 page_id: 6
referenced_name: HisWay referenced_name: HisWay
link_type: W link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_2: first_page_2:
id: 9 id: 9
page_id: 6 page_id: 6
referenced_name: MyWay referenced_name: MyWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_3: first_page_3:
id: 10 id: 10
page_id: 6 page_id: 6
referenced_name: ThatWay referenced_name: ThatWay
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_4: first_page_4:
id: 11 id: 11
page_id: 6 page_id: 6
referenced_name: OverThere referenced_name: OverThere
link_type: W link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_5: first_page_5:
id: 12 id: 12
page_id: 6 page_id: 6
referenced_name: SmartEngine referenced_name: SmartEngine
link_type: L link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
oak_1: oak_1:
id: 13 id: 13
page_id: 7 page_id: 7
referenced_name: trees referenced_name: trees
link_type: C link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>
elephant_1: elephant_1:
id: 14 id: 14
page_id: 8 page_id: 8
referenced_name: animals referenced_name: animals
link_type: C link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %> created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %> updated_at: <%= Time.now.to_formatted_s(:db) %>

View file

@ -1,377 +1,377 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper') require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class PageRendererTest < Test::Unit::TestCase class PageRendererTest < Test::Unit::TestCase
fixtures :webs, :pages, :revisions, :system, :wiki_references fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup def setup
@wiki = Wiki.new @wiki = Wiki.new
@web = webs(:test_wiki) @web = webs(:test_wiki)
@page = pages(:home_page) @page = pages(:home_page)
@revision = revisions(:home_page_second_revision) @revision = revisions(:home_page_second_revision)
end end
def test_wiki_word_linking def test_wiki_word_linking
@web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated', @web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated',
Time.now, 'DavidHeinemeierHansson', test_renderer) Time.now, 'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' + assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' +
'<a href="../show/EverBeenHated">?</a></span></p>', '<a href="../show/EverBeenHated">?</a></span></p>',
rendered_content(@web.page("SecondPage"))) rendered_content(@web.page("SecondPage")))
@web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now, @web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now,
'DavidHeinemeierHansson', test_renderer) 'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' + assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' +
'href="../show/EverBeenHated">Ever Been Hated</a></p>', 'href="../show/EverBeenHated">Ever Been Hated</a></p>',
rendered_content(@web.page("SecondPage"))) rendered_content(@web.page("SecondPage")))
end end
def test_wiki_words def test_wiki_words
assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ), assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ),
test_renderer(@revision).wiki_words.sort test_renderer(@revision).wiki_words.sort
@wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me', test_renderer) @wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me', test_renderer)
assert_equal [], test_renderer(@wiki.read_page('wiki1', 'NoWikiWord').revisions.last).wiki_words assert_equal [], test_renderer(@wiki.read_page('wiki1', 'NoWikiWord').revisions.last).wiki_words
end end
def test_existing_pages def test_existing_pages
assert_equal %w( MyWay SmartEngine ThatWay ), test_renderer(@revision).existing_pages.sort assert_equal %w( MyWay SmartEngine ThatWay ), test_renderer(@revision).existing_pages.sort
end end
def test_unexisting_pages def test_unexisting_pages
assert_equal %w( HisWay SmartEngineGUI ), test_renderer(@revision).unexisting_pages.sort assert_equal %w( HisWay SmartEngineGUI ), test_renderer(@revision).unexisting_pages.sort
end end
def test_content_with_wiki_links def test_content_with_wiki_links
assert_equal '<p><span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' + assert_equal '<p><span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
'would be <a class="existingWikiWord" href="../show/MyWay">My Way</a> in kinda ' + 'would be <a class="existingWikiWord" href="../show/MyWay">My Way</a> in kinda ' +
'<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' + '<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' +
'<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' + '<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere&#8212;see ' + 'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' + '<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI' + '<span class="newWikiWord">Smart Engine GUI' +
'<a href="../show/SmartEngineGUI">?</a></span></p>', '<a href="../show/SmartEngineGUI">?</a></span></p>',
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
def test_markdown def test_markdown
set_web_property :markup, :markdown set_web_property :markup, :markdown
assert_markup_parsed_as( assert_markup_parsed_as(
%{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} + %{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} +
%{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>}, %{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>},
"My Headline\n===========\n\nthat SmartEngineGUI") "My Headline\n===========\n\nthat SmartEngineGUI")
code_block = [ code_block = [
'This is a code block:', 'This is a code block:',
'', '',
' def a_method(arg)', ' def a_method(arg)',
' return ThatWay', ' return ThatWay',
'', '',
'Nice!' 'Nice!'
].join("\n") ].join("\n")
assert_markup_parsed_as( assert_markup_parsed_as(
%{<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\n} + %{<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\n} +
%{return ThatWay\n</code></pre>\n\n<p>Nice!</p>}, %{return ThatWay\n</code></pre>\n\n<p>Nice!</p>},
code_block) code_block)
end end
def test_markdown_hyperlink_with_slash def test_markdown_hyperlink_with_slash
# in response to a bug, see http://dev.instiki.org/attachment/ticket/177 # in response to a bug, see http://dev.instiki.org/attachment/ticket/177
set_web_property :markup, :markdown set_web_property :markup, :markdown
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><a href="http://example/with/slash">text</a></p>', '<p><a href="http://example/with/slash">text</a></p>',
'[text](http://example/with/slash)') '[text](http://example/with/slash)')
end end
def test_mixed_formatting def test_mixed_formatting
textile_and_markdown = [ textile_and_markdown = [
'Markdown heading', 'Markdown heading',
'================', '================',
'', '',
'h2. Textile heading', 'h2. Textile heading',
'', '',
'*some* **text** _with_ -styles-', '*some* **text** _with_ -styles-',
'', '',
'* list 1', '* list 1',
'* list 2' '* list 2'
].join("\n") ].join("\n")
set_web_property :markup, :markdown set_web_property :markup, :markdown
assert_markup_parsed_as( assert_markup_parsed_as(
"<h1>Markdown heading</h1>\n\n" + "<h1>Markdown heading</h1>\n\n" +
"<p>h2. Textile heading</p>\n\n" + "<p>h2. Textile heading</p>\n\n" +
"<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" + "<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" +
"<ul>\n<li>list 1</li>\n<li>list 2</li>\n</ul>", "<ul>\n<li>list 1</li>\n<li>list 2</li>\n</ul>",
textile_and_markdown) textile_and_markdown)
set_web_property :markup, :textile set_web_property :markup, :textile
assert_markup_parsed_as( assert_markup_parsed_as(
"<p>Markdown heading<br />================</p>\n\n\n\t<h2>Textile heading</h2>" + "<p>Markdown heading<br />================</p>\n\n\n\t<h2>Textile heading</h2>" +
"\n\n\n\t<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>" + "\n\n\n\t<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>" +
"\n\n\n\t<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>", "\n\n\n\t<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown) textile_and_markdown)
set_web_property :markup, :mixed set_web_property :markup, :mixed
assert_markup_parsed_as( assert_markup_parsed_as(
"<h1>Markdown heading</h1>\n\n\n\t<h2>Textile heading</h2>\n\n\n\t" + "<h1>Markdown heading</h1>\n\n\n\t<h2>Textile heading</h2>\n\n\n\t" +
"<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>\n\n\n\t" + "<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>\n\n\n\t" +
"<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>", "<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown) textile_and_markdown)
end end
def test_rdoc def test_rdoc
set_web_property :markup, :rdoc set_web_property :markup, :rdoc
@revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI', @revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI',
:author => Author.new('DavidHeinemeierHansson')) :author => Author.new('DavidHeinemeierHansson'))
assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" + assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" +
"<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n", "<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n",
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
def test_content_with_auto_links def test_content_with_auto_links
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' + '<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' + 'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>', '<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com') 'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
end end
def test_content_with_aliased_links def test_content_with_aliased_links
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' + '<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' +
'</a> go by any other name?</p>', '</a> go by any other name?</p>',
'Would a [[SmartEngine|clever motor]] go by any other name?') 'Would a [[SmartEngine|clever motor]] go by any other name?')
end end
def test_content_with_wikiword_in_em def test_content_with_wikiword_in_em
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><em>should we go <a class="existingWikiWord" href="../show/ThatWay">' + '<p><em>should we go <a class="existingWikiWord" href="../show/ThatWay">' +
'That Way</a> or <span class="newWikiWord">This Way<a href="../show/ThisWay">?</a>' + 'That Way</a> or <span class="newWikiWord">This Way<a href="../show/ThisWay">?</a>' +
'</span> </em></p>', '</span> </em></p>',
'_should we go ThatWay or ThisWay _') '_should we go ThatWay or ThisWay _')
end end
def test_content_with_wikiword_in_tag def test_content_with_wikiword_in_tag
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>', '<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>',
'That is some <em style="WikiWord">Stylish Emphasis</em>') 'That is some <em style="WikiWord">Stylish Emphasis</em>')
end end
def test_content_with_escaped_wikiword def test_content_with_escaped_wikiword
# there should be no wiki link # there should be no wiki link
assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord') assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord')
end end
def test_content_with_pre_blocks def test_content_with_pre_blocks
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre></p>', '<p>A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre></p>',
'A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>') 'A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>')
end end
def test_content_with_autolink_in_parentheses def test_content_with_autolink_in_parentheses
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' + '<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' +
'http://www.w3c.org</a>) sets web standards</p>', 'http://www.w3c.org</a>) sets web standards</p>',
'The W3C body (http://www.w3c.org) sets web standards') 'The W3C body (http://www.w3c.org) sets web standards')
end end
def test_content_with_link_in_parentheses def test_content_with_link_in_parentheses
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>(<a href="http://wiki.org/wiki.cgi?WhatIsWiki">What is a wiki?</a>)</p>', '<p>(<a href="http://wiki.org/wiki.cgi?WhatIsWiki">What is a wiki?</a>)</p>',
'("What is a wiki?":http://wiki.org/wiki.cgi?WhatIsWiki)') '("What is a wiki?":http://wiki.org/wiki.cgi?WhatIsWiki)')
end end
def test_content_with_image_link def test_content_with_image_link
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is a Textile image link.</p>', '<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is a Textile image link.</p>',
'This !http://hobix.com/sample.jpg! is a Textile image link.') 'This !http://hobix.com/sample.jpg! is a Textile image link.')
end end
def test_content_with_inlined_img_tag def test_content_with_inlined_img_tag
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.</p>', '<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.</p>',
'This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.') 'This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.')
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.</p>', '<p>This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.</p>',
'This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.') 'This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.')
end end
def test_nowiki_tag def test_nowiki_tag
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>Do not mark up [[this text]] or http://www.thislink.com.</p>', '<p>Do not mark up [[this text]] or http://www.thislink.com.</p>',
'Do not mark up <nowiki>[[this text]]</nowiki> ' + 'Do not mark up <nowiki>[[this text]]</nowiki> ' +
'or <nowiki>http://www.thislink.com</nowiki>.') 'or <nowiki>http://www.thislink.com</nowiki>.')
end end
def test_multiline_nowiki_tag def test_multiline_nowiki_tag
assert_markup_parsed_as( assert_markup_parsed_as(
"<p>Do not mark \n up [[this text]] \nand http://this.url.com but markup " + "<p>Do not mark \n up [[this text]] \nand http://this.url.com but markup " +
'<span class="newWikiWord">this<a href="../show/this">?</a></span></p>', '<span class="newWikiWord">this<a href="../show/this">?</a></span></p>',
"Do not <nowiki>mark \n up [[this text]] \n" + "Do not <nowiki>mark \n up [[this text]] \n" +
"and http://this.url.com </nowiki> but markup [[this]]") "and http://this.url.com </nowiki> but markup [[this]]")
end end
def test_content_with_bracketted_wiki_word def test_content_with_bracketted_wiki_word
set_web_property :brackets_only, true set_web_property :brackets_only, true
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>This is a WikiWord and a tricky name <span class="newWikiWord">' + '<p>This is a WikiWord and a tricky name <span class="newWikiWord">' +
'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>', 'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>',
'This is a WikiWord and a tricky name [[Sperberg-McQueen]].') 'This is a WikiWord and a tricky name [[Sperberg-McQueen]].')
end end
def test_content_for_export def test_content_for_export
assert_equal '<p><span class="newWikiWord">His Way</span> would be ' + assert_equal '<p><span class="newWikiWord">His Way</span> would be ' +
'<a class="existingWikiWord" href="MyWay.html">My Way</a> in kinda ' + '<a class="existingWikiWord" href="MyWay.html">My Way</a> in kinda ' +
'<a class="existingWikiWord" href="ThatWay.html">That Way</a> in ' + '<a class="existingWikiWord" href="ThatWay.html">That Way</a> in ' +
'<span class="newWikiWord">His Way</span> though ' + '<span class="newWikiWord">His Way</span> though ' +
'<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere&#8212;see ' + '<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' + '<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI</span></p>', '<span class="newWikiWord">Smart Engine GUI</span></p>',
test_renderer(@revision).display_content_for_export test_renderer(@revision).display_content_for_export
end end
def test_double_replacing def test_double_replacing
@revision.content = "VersionHistory\r\n\r\ncry VersionHistory" @revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
assert_equal '<p><span class="newWikiWord">Version History' + assert_equal '<p><span class="newWikiWord">Version History' +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " + "<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
'<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' + '<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' +
'</span></p>', '</span></p>',
test_renderer(@revision).display_content test_renderer(@revision).display_content
@revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory" @revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" + assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " + "<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
"<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" + "<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" +
"</span></p>", "</span></p>",
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
def test_difficult_wiki_words def test_difficult_wiki_words
@revision.content = "[[It's just awesome GUI!]]" @revision.content = "[[It's just awesome GUI!]]"
assert_equal "<p><span class=\"newWikiWord\">It's just awesome GUI!" + assert_equal "<p><span class=\"newWikiWord\">It's just awesome GUI!" +
"<a href=\"../show/It%27s+just+awesome+GUI%21\">?</a></span></p>", "<a href=\"../show/It%27s+just+awesome+GUI%21\">?</a></span></p>",
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
def test_revisions_diff def test_revisions_diff
Revision.create(:page => @page, :content => 'What a blue and lovely morning', Revision.create(:page => @page, :content => 'What a blue and lovely morning',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now) :author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
Revision.create(:page => @page, :content => 'What a red and lovely morning today', Revision.create(:page => @page, :content => 'What a red and lovely morning today',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now) :author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
assert_equal "<p>What a <del class=\"diffmod\">blue</del><ins class=\"diffmod\">red" + assert_equal "<p>What a <del class=\"diffmod\">blue</del><ins class=\"diffmod\">red" +
"</ins> and lovely morning<ins class=\"diffins\"> today</ins></p>", test_renderer(@page.revisions.last).display_diff "</ins> and lovely morning<ins class=\"diffins\"> today</ins></p>", test_renderer(@page.revisions.last).display_diff
end end
def test_link_to_file def test_link_to_file
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>', '<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>',
'[[doc.pdf:file]]') '[[doc.pdf:file]]')
end end
def test_link_to_pic def test_link_to_pic
WikiFile.delete_all WikiFile.delete_all
require 'fileutils' require 'fileutils'
FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*") FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
@web.wiki_files.create(:file_name => 'square.jpg', :description => 'Square', :content => 'never mind') @web.wiki_files.create(:file_name => 'square.jpg', :description => 'Square', :content => 'never mind')
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><img alt="Square" src="../file/square.jpg" /></p>', '<p><img alt="Square" src="../file/square.jpg" /></p>',
'[[square.jpg|Square:pic]]') '[[square.jpg|Square:pic]]')
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><img alt="square.jpg" src="../file/square.jpg" /></p>', '<p><img alt="square.jpg" src="../file/square.jpg" /></p>',
'[[square.jpg:pic]]') '[[square.jpg:pic]]')
end end
def test_link_to_non_existant_pic def test_link_to_non_existant_pic
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant<a href="../file/NonExistant.jpg">?</a>' + '<p><span class="newWikiWord">NonExistant<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>', '</span></p>',
'[[NonExistant.jpg|NonExistant:pic]]') '[[NonExistant.jpg|NonExistant:pic]]')
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant.jpg<a href="../file/NonExistant.jpg">?</a>' + '<p><span class="newWikiWord">NonExistant.jpg<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>', '</span></p>',
'[[NonExistant.jpg:pic]]') '[[NonExistant.jpg:pic]]')
end end
def test_wiki_link_with_colon def test_wiki_link_with_colon
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>', '<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>',
'[[With:Colon]]') '[[With:Colon]]')
end end
def test_list_with_tildas def test_list_with_tildas
list_with_tildas = <<-EOL list_with_tildas = <<-EOL
* "a":~b * "a":~b
* c~ d * c~ d
EOL EOL
assert_markup_parsed_as( assert_markup_parsed_as(
"<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>", "<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>",
list_with_tildas) list_with_tildas)
end end
def test_textile_image_in_mixed_wiki def test_textile_image_in_mixed_wiki
set_web_property :markup, :mixed set_web_property :markup, :mixed
assert_markup_parsed_as( assert_markup_parsed_as(
"<p><img src=\"http://google.com\" alt=\"\" />\nss</p>", "<p><img src=\"http://google.com\" alt=\"\" />\nss</p>",
"!http://google.com!\r\nss") "!http://google.com!\r\nss")
end end
def test_references_creation_links def test_references_creation_links
new_page = @web.add_page('NewPage', 'HomePage NewPage', new_page = @web.add_page('NewPage', 'HomePage NewPage',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer) Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true) references = new_page.wiki_references(true)
assert_equal 2, references.size assert_equal 2, references.size
assert_equal 'HomePage', references[0].referenced_name assert_equal 'HomePage', references[0].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[0].link_type assert_equal WikiReference::LINKED_PAGE, references[0].link_type
assert_equal 'NewPage', references[1].referenced_name assert_equal 'NewPage', references[1].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[1].link_type assert_equal WikiReference::LINKED_PAGE, references[1].link_type
end end
def test_references_creation_includes def test_references_creation_includes
new_page = @web.add_page('NewPage', '[[!include IncludedPage]]', new_page = @web.add_page('NewPage', '[[!include IncludedPage]]',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer) Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true) references = new_page.wiki_references(true)
assert_equal 1, references.size assert_equal 1, references.size
assert_equal 'IncludedPage', references[0].referenced_name assert_equal 'IncludedPage', references[0].referenced_name
assert_equal WikiReference::INCLUDED_PAGE, references[0].link_type assert_equal WikiReference::INCLUDED_PAGE, references[0].link_type
end end
def test_references_creation_categories def test_references_creation_categories
new_page = @web.add_page('NewPage', "Foo\ncategory: NewPageCategory", new_page = @web.add_page('NewPage', "Foo\ncategory: NewPageCategory",
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer) Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true) references = new_page.wiki_references(true)
assert_equal 1, references.size assert_equal 1, references.size
assert_equal 'NewPageCategory', references[0].referenced_name assert_equal 'NewPageCategory', references[0].referenced_name
assert_equal WikiReference::CATEGORY, references[0].link_type assert_equal WikiReference::CATEGORY, references[0].link_type
end end
private private
def add_sample_pages def add_sample_pages
@in_love = @web.add_page('EverBeenInLove', 'Who am I me', @in_love = @web.add_page('EverBeenInLove', 'Who am I me',
Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson', test_renderer) Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson', test_renderer)
@hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated', @hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated',
Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson', test_renderer) Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson', test_renderer)
end end
def assert_markup_parsed_as(expected_output, input) def assert_markup_parsed_as(expected_output, input)
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor')) revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected' assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected'
end end
def rendered_content(page) def rendered_content(page)
test_renderer(page.revisions.last).display_content test_renderer(page.revisions.last).display_content
end end
end end

View file

@ -1,84 +1,84 @@
require File.dirname(__FILE__) + '/../test_helper' require File.dirname(__FILE__) + '/../test_helper'
require 'fileutils' require 'fileutils'
class WikiFileTest < Test::Unit::TestCase class WikiFileTest < Test::Unit::TestCase
include FileUtils include FileUtils
fixtures :webs, :pages, :revisions, :system, :wiki_references fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup def setup
@web = webs(:test_wiki) @web = webs(:test_wiki)
mkdir_p("#{RAILS_ROOT}/public/wiki1/files/") mkdir_p("#{RAILS_ROOT}/public/wiki1/files/")
rm_rf("#{RAILS_ROOT}/public/wiki1/files/*") rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
WikiFile.delete_all WikiFile.delete_all
end end
def test_basic_store_and_retrieve_ascii_file def test_basic_store_and_retrieve_ascii_file
@web.wiki_files.create(:file_name => 'binary_file', :description => 'Binary file', :content => "\001\002\003") @web.wiki_files.create(:file_name => 'binary_file', :description => 'Binary file', :content => "\001\002\003")
binary = WikiFile.find_by_file_name('binary_file') binary = WikiFile.find_by_file_name('binary_file')
assert_equal "\001\002\003", binary.content assert_equal "\001\002\003", binary.content
end end
def test_basic_store_and_retrieve_binary_file def test_basic_store_and_retrieve_binary_file
@web.wiki_files.create(:file_name => 'text_file', :description => 'Text file', :content => "abc") @web.wiki_files.create(:file_name => 'text_file', :description => 'Text file', :content => "abc")
text = WikiFile.find_by_file_name('text_file') text = WikiFile.find_by_file_name('text_file')
assert_equal "abc", text.content assert_equal "abc", text.content
end end
def test_storing_an_image def test_storing_an_image
rails_gif = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read } rails_gif = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read }
assert_equal rails_gif.size, File.size("#{RAILS_ROOT}/test/fixtures/rails.gif") assert_equal rails_gif.size, File.size("#{RAILS_ROOT}/test/fixtures/rails.gif")
@web.wiki_files.create(:file_name => 'rails.gif', :description => 'Rails logo', :content => rails_gif) @web.wiki_files.create(:file_name => 'rails.gif', :description => 'Rails logo', :content => rails_gif)
rails_gif_from_db = WikiFile.find_by_file_name('rails.gif') rails_gif_from_db = WikiFile.find_by_file_name('rails.gif')
assert_equal rails_gif.size, rails_gif_from_db.content.size assert_equal rails_gif.size, rails_gif_from_db.content.size
assert_equal rails_gif, rails_gif_from_db.content assert_equal rails_gif, rails_gif_from_db.content
end end
def test_mandatory_fields_validations def test_mandatory_fields_validations
assert_validation(:file_name, '', :fail) assert_validation(:file_name, '', :fail)
assert_validation(:file_name, nil, :fail) assert_validation(:file_name, nil, :fail)
assert_validation(:content, '', :fail) assert_validation(:content, '', :fail)
assert_validation(:content, nil, :fail) assert_validation(:content, nil, :fail)
end end
def test_upload_size_validation def test_upload_size_validation
assert_validation(:content, 'a' * 100.kilobytes, :pass) assert_validation(:content, 'a' * 100.kilobytes, :pass)
assert_validation(:content, 'a' * (100.kilobytes + 1), :fail) assert_validation(:content, 'a' * (100.kilobytes + 1), :fail)
end end
def test_file_name_size_validation def test_file_name_size_validation
assert_validation(:file_name, '', :fail) assert_validation(:file_name, '', :fail)
assert_validation(:file_name, 'a', :pass) assert_validation(:file_name, 'a', :pass)
assert_validation(:file_name, 'a' * 50, :pass) assert_validation(:file_name, 'a' * 50, :pass)
assert_validation(:file_name, 'a' * 51, :fail) assert_validation(:file_name, 'a' * 51, :fail)
end end
def test_file_name_pattern_validation def test_file_name_pattern_validation
assert_validation(:file_name, ".. Accep-table File.name", :pass) assert_validation(:file_name, ".. Accep-table File.name", :pass)
assert_validation(:file_name, "/bad", :fail) assert_validation(:file_name, "/bad", :fail)
assert_validation(:file_name, "~bad", :fail) assert_validation(:file_name, "~bad", :fail)
assert_validation(:file_name, "..\bad", :fail) assert_validation(:file_name, "..\bad", :fail)
assert_validation(:file_name, "\001bad", :fail) assert_validation(:file_name, "\001bad", :fail)
assert_validation(:file_name, ".", :fail) assert_validation(:file_name, ".", :fail)
assert_validation(:file_name, "..", :fail) assert_validation(:file_name, "..", :fail)
end end
def test_find_by_file_name def test_find_by_file_name
assert_equal @file1, WikiFile.find_by_file_name('file1.txt') assert_equal @file1, WikiFile.find_by_file_name('file1.txt')
assert_nil WikiFile.find_by_file_name('unknown_file') assert_nil WikiFile.find_by_file_name('unknown_file')
end end
def assert_validation(field, value, expected_result) def assert_validation(field, value, expected_result)
values = {:file_name => '0', :description => '0', :content => '0'} values = {:file_name => '0', :description => '0', :content => '0'}
raise "WikiFile has no attribute named #{field.inspect}" unless values.has_key?(field) raise "WikiFile has no attribute named #{field.inspect}" unless values.has_key?(field)
values[field] = value values[field] = value
new_object = @web.wiki_files.create(values) new_object = @web.wiki_files.create(values)
if expected_result == :pass then assert(new_object.valid?, new_object.errors.inspect) if expected_result == :pass then assert(new_object.valid?, new_object.errors.inspect)
elsif expected_result == :fail then assert(!new_object.valid?) elsif expected_result == :fail then assert(!new_object.valid?)
else raise "Unknown value of expected_result: #{expected_result.inspect}" else raise "Unknown value of expected_result: #{expected_result.inspect}"
end end
end end
end end