Compare commits

..

2 Commits

Author SHA1 Message Date
Bart Kamphorst 906dab700f Normalize the page contents used to create a PreviewPage. Fixes #1617. 2020-09-20 18:32:15 +02:00
Bart Kamphorst c5894dd4df Filter _Template content. Proposed solution to #1603. 2020-08-25 16:55:00 +02:00
60 changed files with 412 additions and 852 deletions
+1 -2
View File
@@ -1,8 +1,7 @@
rvm: rvm:
- 2.4.0 - 2.4.0
- 2.6.0 - 2.6.0
- 3.0.0 - jruby-9.2.9.0
- jruby-9.2.18.0
jdk: jdk:
- oraclejdk9 - oraclejdk9
before_install: before_install:
+2 -4
View File
@@ -21,7 +21,7 @@ Before submitting an issue, **please carefully look through the following places
Security vulnerabilities can be reported directly to the maintainers using these GPG keys: Security vulnerabilities can be reported directly to the maintainers using these GPG keys:
* [@dometto](https://keys.openpgp.org/vks/v1/by-fingerprint/02354CC9F820B52CC2791979BB8CCC95FD83B795) * [@dometto](https://pgp.mit.edu/pks/lookup?op=vindex&search=0xD637E455CD3E27BF)
Lastly, please **consider helping out** by opening a Pull Request! Lastly, please **consider helping out** by opening a Pull Request!
@@ -63,8 +63,6 @@ Pull Requests fixing bugs, implementing new features, or updating documentation
bundle exec rake test bundle exec rake test
``` ```
To profile slow tests, you can use `bundle exec rake test TESTOPTS="--verbose"`.
### Working with test repositories ### Working with test repositories
An example of how to add a test file to the bare repository lotr.git. An example of how to add a test file to the bare repository lotr.git.
@@ -72,7 +70,7 @@ An example of how to add a test file to the bare repository lotr.git.
``` ```
mkdir tmp mkdir tmp
cd tmp cd tmp
git clone ../test/examples/lotr.git/ git clone ../lotr.git/
git log git log
echo "test" > test.md echo "test" > test.md
git add . git add .
+2 -1
View File
@@ -6,4 +6,5 @@ end
gemspec gemspec
gem 'rake', '~> 13.0' gem "rake", '~> 12.3', '>= 12.3.3'
-19
View File
@@ -1,22 +1,3 @@
# 5.2.3 2021-04-18
* Fix bug preventing page titles from being displayed
# 5.2.1 2021-02-25
* Fix include call to a missing asset (@benjaminwil). This caused slow first page loads on JRuby.
# 5.2 2021-02-24
* Improved styling and Primer upgrade (@benjaminwil)
* Add redirect to rename commit (@ViChyavIn)
* Updated dependencies
* Bugfixes
# 5.1.2
* Guard against malicious filenames in breadcrumbs
# 5.1 # 5.1
* Bugfixes * Bugfixes
+2 -1
View File
@@ -4,7 +4,8 @@ gollum -- A git-based Wiki
[![Gem Version](https://badge.fury.io/rb/gollum.svg)](http://badge.fury.io/rb/gollum) [![Gem Version](https://badge.fury.io/rb/gollum.svg)](http://badge.fury.io/rb/gollum)
[![Build Status](https://travis-ci.org/gollum/gollum.svg?branch=master)](https://travis-ci.org/gollum/gollum) [![Build Status](https://travis-ci.org/gollum/gollum.svg?branch=master)](https://travis-ci.org/gollum/gollum)
[![Open Source Helpers](https://www.codetriage.com/gollum/gollum/badges/users.svg)](https://www.codetriage.com/gollum/gollum) [![Open Source Helpers](https://www.codetriage.com/gollum/gollum/badges/users.svg)](https://www.codetriage.com/gollum/gollum)
[![Cutting Edge Dependency Status](https://dometto-cuttingedge.herokuapp.com/github/gollum/gollum/svg 'Cutting Edge Dependency Status')](https://dometto-cuttingedge.herokuapp.com/github/gollum/gollum/info)
**Please update to gollum 5.1.1 to counter a recent exploit in the kramdown rendering gem, [CVE-2020-14001](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14001)**
**Gollum version 5.0 is out!** See [here](https://github.com/gollum/gollum/wiki/5.0-release-notes) for a list of changes and new features compared to Gollum version 4.x, and see some [Screenshots](https://github.com/gollum/gollum/wiki/Screenshots) of Gollum's features. **Gollum version 5.0 is out!** See [here](https://github.com/gollum/gollum/wiki/5.0-release-notes) for a list of changes and new features compared to Gollum version 4.x, and see some [Screenshots](https://github.com/gollum/gollum/wiki/Screenshots) of Gollum's features.
+1 -1
View File
@@ -152,7 +152,7 @@ MSG
opts.on('--template-dir [PATH]', 'Specify custom mustache template directory.') do |path| opts.on('--template-dir [PATH]', 'Specify custom mustache template directory.') do |path|
wiki_options[:template_dir] = path wiki_options[:template_dir] = path
end end
opts.on('--template-page', 'Use _Template.{ext} as a template for new pages.') do opts.on('--template-page', 'Use _Template in root as a template for new pages.') do
wiki_options[:template_page] = true wiki_options[:template_page] = true
end end
opts.on('--lenient-tag-lookup', 'Internal links resolve case-insensitively, will treat spaces as hyphens, and will match the first page found with a certain filename, anywhere in the repository. Provides compatibility with Gollum 4.x.') do opts.on('--lenient-tag-lookup', 'Internal links resolve case-insensitively, will treat spaces as hyphens, and will match the first page found with a certain filename, anywhere in the repository. Provides compatibility with Gollum 4.x.') do
-66
View File
@@ -1,66 +0,0 @@
#!/usr/bin/env ruby
#
# Distributed under the terms of the MIT License.
#
# Author: Sam Baskinger <basking2@yahoo.com>
#
# Description: gollum-post is an example script that shows how
# to post a file to Gollum. This may be used
# to build scripts around CI/CD pipelines that
# publish their documentation to Gollum.
#
require 'uri'
require 'mechanize'
require 'digest'
GOLLUM=URI('https://mygollum.server')
m = Mechanize.new()
page="TestPage"
path="/automated/docs"
format="asciidoc"
content="""
= This is #{page}
This page is automatically generated.
"""
message='Posting current documentation.'
# Check if the page exists.
p = m.get("#{GOLLUM}#{path}/#{page}")
# If we were redirected to the creat page...
if p.uri.to_s =~ /\/gollum\/create/
# ... then create the page.
p = m.post("#{GOLLUM}/gollum/create",
'keybinding' => 'default',
'page' => page,
'path' => path,
'format' => 'asciidoc',
'message' => 'Publish bot.',
'content' => content)
else
# ... else, get the previous content and update it.
p = m.get("#{GOLLUM}/gollum/edit#{path}/#{page}")
# Get the previous content. You _could_ check if this is unchanged at this
# step and post nothing.
previous_content = p.xpath('//textarea[@id="gollum-editor-body"]')[0].text
# The previous ETag is the Git SHA-1. We need this to replace the previous contents.
prev_etag = Digest::SHA1.hexdigest("blob #{previous_content.length}\0#{previous_content}")
# Post the updated document using the ETag of the previous document to avoid collisions.
p = m.post("#{GOLLUM}/gollum/edit#{path}/#{page}",
'keybinding' => 'default',
'page' => page,
'path' => path,
'format' => 'asciidoc',
'message' => message,
'etag' => prev_etag,
'content' => content)
end
+17 -19
View File
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 1.9' s.required_ruby_version = '>= 1.9'
s.name = 'gollum' s.name = 'gollum'
s.version = '5.2.3' s.version = '5.1.1'
s.date = '2021-04-18' s.date = '2020-08-11'
s.license = 'MIT' s.license = 'MIT'
s.summary = 'A simple, Git-powered wiki.' s.summary = 'A simple, Git-powered wiki.'
@@ -23,22 +23,21 @@ Gem::Specification.new do |s|
s.rdoc_options = ['--charset=UTF-8'] s.rdoc_options = ['--charset=UTF-8']
s.extra_rdoc_files = %w[README.md LICENSE] s.extra_rdoc_files = %w[README.md LICENSE]
s.add_dependency 'gollum-lib', '~> 5.1' s.add_dependency 'gollum-lib', '~> 5.0'
s.add_dependency 'kramdown', '~> 2.3' s.add_dependency 'kramdown', '~> 2.3'
s.add_dependency 'kramdown-parser-gfm', '~> 1.1.0' s.add_dependency 'kramdown-parser-gfm', '~> 1.0.0'
s.add_dependency 'sinatra', '~> 2.0' s.add_dependency 'sinatra', '~> 2.0'
s.add_dependency 'sinatra-contrib', '~> 2.0' s.add_dependency 'sinatra-contrib', '~> 2.0'
s.add_dependency 'mustache-sinatra', '~> 1.0' s.add_dependency 'mustache', ['>= 0.99.5', '< 1.0.0']
s.add_dependency 'useragent', '~> 0.16.2' s.add_dependency 'useragent', '~> 0.16.2'
s.add_dependency 'gemojione', '~> 4.1' s.add_dependency 'gemojione', '~> 4.1'
s.add_dependency 'octicons', '~> 12.0' s.add_dependency 'octicons', '~> 8.5'
s.add_dependency 'sprockets', '~> 3.7' s.add_dependency 'sprockets', '~> 3.7'
s.add_dependency 'sass', '~> 3.5' s.add_dependency 'sass', '~> 3.5'
s.add_dependency 'uglifier', '~> 4.2' s.add_dependency 'uglifier', '~> 3.2'
s.add_dependency 'sprockets-helpers', '~> 1.2' s.add_dependency 'sprockets-helpers', '~> 1.2'
s.add_dependency 'rss', '~> 0.2.9' s.add_dependency 'rss', '~> 0.2.9'
s.add_dependency 'therubyrhino', '~> 2.1.0' s.add_dependency 'therubyrhino', '~> 2.1.0'
s.add_dependency 'webrick', '~> 1.7'
s.add_development_dependency 'rack-test', '~> 0.6.3' s.add_development_dependency 'rack-test', '~> 0.6.3'
s.add_development_dependency 'shoulda', '~> 3.6.0' s.add_development_dependency 'shoulda', '~> 3.6.0'
@@ -46,6 +45,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'twitter_cldr', '~> 3.2.0' s.add_development_dependency 'twitter_cldr', '~> 3.2.0'
s.add_development_dependency 'mocha', '~> 1.8.0' s.add_development_dependency 'mocha', '~> 1.8.0'
s.add_development_dependency 'test-unit', '~> 3.3.0' s.add_development_dependency 'test-unit', '~> 3.3.0'
s.add_development_dependency 'webrick', '~> 1.4.2'
# = MANIFEST = # = MANIFEST =
s.files = %w[ s.files = %w[
@@ -59,7 +59,6 @@ Gem::Specification.new do |s|
bin/gollum-migrate-tags bin/gollum-migrate-tags
config.rb config.rb
config.ru config.ru
contrib/automation/gollum-post
contrib/openrc/conf.d/gollum contrib/openrc/conf.d/gollum
contrib/openrc/init.d/gollum contrib/openrc/init.d/gollum
contrib/systemd/gollum@.service contrib/systemd/gollum@.service
@@ -69,15 +68,15 @@ Gem::Specification.new do |s|
lib/gollum/app.rb lib/gollum/app.rb
lib/gollum/assets.rb lib/gollum/assets.rb
lib/gollum/helpers.rb lib/gollum/helpers.rb
lib/gollum/public/assets/.sprockets-manifest-de7bb79aec424e55af1acdcc4237b301.json lib/gollum/public/assets/.sprockets-manifest-459226ba5fc211b78ba9a3aa6ebde96c.json
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js lib/gollum/public/assets/app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js.gz lib/gollum/public/assets/app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js.gz
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css lib/gollum/public/assets/app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css.gz lib/gollum/public/assets/app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css.gz
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css
lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css.gz lib/gollum/public/assets/criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css.gz
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js lib/gollum/public/assets/editor-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js.gz lib/gollum/public/assets/editor-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js.gz
lib/gollum/public/assets/print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css lib/gollum/public/assets/print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css
lib/gollum/public/assets/print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css.gz lib/gollum/public/assets/print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css.gz
lib/gollum/public/gollum/javascript/HOWTO_UPDATE_ACE.md lib/gollum/public/gollum/javascript/HOWTO_UPDATE_ACE.md
@@ -1175,18 +1174,18 @@ Gem::Specification.new do |s|
lib/gollum/public/gollum/javascript/jquery-1.7.2.min.js lib/gollum/public/gollum/javascript/jquery-1.7.2.min.js
lib/gollum/public/gollum/javascript/jquery.resize.js lib/gollum/public/gollum/javascript/jquery.resize.js
lib/gollum/public/gollum/javascript/mousetrap.min.js lib/gollum/public/gollum/javascript/mousetrap.min.js
lib/gollum/public/gollum/javascript/polyfills.js
lib/gollum/public/gollum/stylesheets/_base.scss lib/gollum/public/gollum/stylesheets/_base.scss
lib/gollum/public/gollum/stylesheets/_breakpoint.scss lib/gollum/public/gollum/stylesheets/_breakpoint.scss
lib/gollum/public/gollum/stylesheets/_component.scss lib/gollum/public/gollum/stylesheets/_component.scss
lib/gollum/public/gollum/stylesheets/_features.scss lib/gollum/public/gollum/stylesheets/_features.scss
lib/gollum/public/gollum/stylesheets/_layout.scss
lib/gollum/public/gollum/stylesheets/_spinners.scss lib/gollum/public/gollum/stylesheets/_spinners.scss
lib/gollum/public/gollum/stylesheets/app.scss lib/gollum/public/gollum/stylesheets/app.scss
lib/gollum/public/gollum/stylesheets/criticmarkup.scss lib/gollum/public/gollum/stylesheets/criticmarkup.scss
lib/gollum/public/gollum/stylesheets/dialog.scss lib/gollum/public/gollum/stylesheets/dialog.scss
lib/gollum/public/gollum/stylesheets/editor.scss lib/gollum/public/gollum/stylesheets/editor.scss
lib/gollum/public/gollum/stylesheets/emoji.scss lib/gollum/public/gollum/stylesheets/emoji.scss
lib/gollum/public/gollum/stylesheets/primer.css lib/gollum/public/gollum/stylesheets/primer.scss
lib/gollum/public/gollum/stylesheets/print.scss lib/gollum/public/gollum/stylesheets/print.scss
lib/gollum/public/gollum/stylesheets/spinner.scss lib/gollum/public/gollum/stylesheets/spinner.scss
lib/gollum/public/gollum/stylesheets/tables.scss lib/gollum/public/gollum/stylesheets/tables.scss
@@ -1203,7 +1202,6 @@ Gem::Specification.new do |s|
lib/gollum/templates/history_authors/none.mustache lib/gollum/templates/history_authors/none.mustache
lib/gollum/templates/latest_changes.mustache lib/gollum/templates/latest_changes.mustache
lib/gollum/templates/layout.mustache lib/gollum/templates/layout.mustache
lib/gollum/templates/mobilenav.mustache
lib/gollum/templates/navbar.mustache lib/gollum/templates/navbar.mustache
lib/gollum/templates/overview.mustache lib/gollum/templates/overview.mustache
lib/gollum/templates/page.mustache lib/gollum/templates/page.mustache
+14 -14
View File
@@ -12,25 +12,25 @@ require 'rhino' if RUBY_PLATFORM == 'java'
require File.expand_path('../gollum/uri_encode_component', __FILE__) require File.expand_path('../gollum/uri_encode_component', __FILE__)
module Gollum module Gollum
VERSION = '5.2.3' VERSION = '5.1.1'
def self.assets_path def self.assets_path
::File.expand_path('gollum/public', ::File.dirname(__FILE__)) ::File.expand_path('gollum/public', ::File.dirname(__FILE__))
end end
class TemplateFilter class Error < StandardError;
@@filters = {}
def self.add_filter(pattern, &replacement)
@@filters[pattern] = replacement
end
def self.apply_filters(data)
@@filters.each do |pattern, replacement|
data.gsub!(pattern, replacement.call)
end
data
end
end end
class DuplicatePageError < Error
attr_accessor :dir
attr_accessor :existing_path
attr_accessor :attempted_path
def initialize(dir, existing, attempted, message = nil)
@dir = dir
@existing_path = existing
@attempted_path = attempted
super(message || "Cannot write #{@dir}/#{@attempted_path}, found #{@dir}/#{@existing_path}.")
end
end
end end
+15 -17
View File
@@ -1,5 +1,4 @@
# encoding: UTF-8 # ~*~ encoding: utf-8 ~*~
require 'cgi' require 'cgi'
require 'sinatra' require 'sinatra'
require 'sinatra/namespace' require 'sinatra/namespace'
@@ -70,8 +69,6 @@ module Precious
register Sinatra::Namespace register Sinatra::Namespace
include Precious::Helpers include Precious::Helpers
Encoding.default_external = "UTF-8"
dir = File.dirname(File.expand_path(__FILE__)) dir = File.dirname(File.expand_path(__FILE__))
set :sprockets, ::Precious::Assets.sprockets(dir) set :sprockets, ::Precious::Assets.sprockets(dir)
@@ -120,7 +117,7 @@ module Precious
@js = settings.wiki_options[:js] @js = settings.wiki_options[:js]
@mathjax_config = settings.wiki_options[:mathjax_config] @mathjax_config = settings.wiki_options[:mathjax_config]
@use_static_assets = settings.wiki_options.fetch(:static, settings.environment != :development) @use_static_assets = settings.wiki_options.fetch(:static, settings.environment == :production || settings.environment == :staging)
@static_assets_path = settings.wiki_options.fetch(:static_assets_path, ::File.join(File.dirname(__FILE__), 'public/assets')) @static_assets_path = settings.wiki_options.fetch(:static_assets_path, ::File.join(File.dirname(__FILE__), 'public/assets'))
@mathjax_path = ::File.join(File.dirname(__FILE__), 'public/gollum/javascript/MathJax') @mathjax_path = ::File.join(File.dirname(__FILE__), 'public/gollum/javascript/MathJax')
@@ -306,13 +303,12 @@ module Precious
redirect to("/#{page.escaped_url_path}") redirect to("/#{page.escaped_url_path}")
return return
end end
committer.commit
# Renaming preserves format, so add the page's format to the renamed path to retrieve the renamed page # Renaming preserves format, so add the page's format to the renamed path to retrieve the renamed page
new_path = "#{rename}.#{Gollum::Page.format_to_ext(page.format)}" new_path = "#{rename}.#{Gollum::Page.format_to_ext(page.format)}"
# Add a redirect from the old page to the new # Add a redirect from the old page to the new
wiki.add_redirect(page.url_path, clean_url(new_path), commit) if @redirects_enabled wiki.add_redirect(page.url_path, clean_url(new_path)) if @redirects_enabled
committer.commit
page = wiki_page(new_path).page page = wiki_page(new_path).page
return if page.nil? return if page.nil?
@@ -322,8 +318,9 @@ module Precious
post '/edit/*' do post '/edit/*' do
etag = params[:etag] etag = params[:etag]
path = "/#{clean_url(sanitize_empty_params(params[:path]))}" path = "/#{clean_url(sanitize_empty_params(params[:path]))}"
page_name = CGI.unescape(params[:page])
wiki = wiki_new wiki = wiki_new
page = wiki.page(::File.join(path, params[:page])) page = wiki.page(::File.join(path, page_name))
return if page.nil? return if page.nil?
if etag != page.sha if etag != page.sha
@@ -355,11 +352,17 @@ module Precious
get '/create/*' do get '/create/*' do
forbid unless @allow_editing forbid unless @allow_editing
if settings.wiki_options[:template_page] then
temppage = wiki_page('/_Template')
@template_page = (temppage.page != nil) ? temppage.page.raw_data : 'Template page option is set, but no /_Template page is present or committed.'
if defined?(Gollum::TemplateFilter)
@template_page = Gollum::TemplateFilter.filter(@template_page)
end
end
wikip = wiki_page(params[:splat].first) wikip = wiki_page(params[:splat].first)
@name = wikip.name @name = wikip.name
@ext = wikip.ext @ext = wikip.ext
@path = wikip.path @path = wikip.path
@template_page = load_template(@path) if settings.wiki_options[:template_page]
@allow_uploads = wikip.wiki.allow_uploads @allow_uploads = wikip.wiki.allow_uploads
@upload_dest = find_upload_dest(wikip.fullpath) @upload_dest = find_upload_dest(wikip.fullpath)
@@ -417,8 +420,8 @@ module Precious
post '/preview' do post '/preview' do
wiki = wiki_new wiki = wiki_new
@name = params[:page] ? strip_page_name(params[:page]) : 'Preview' @name = params[:page] ? strip_page_name(CGI.unescape(params[:page])) : 'Preview'
@page = wiki.preview_page(@name, params[:content], params[:format]) @page = wiki.preview_page(@name, wiki.normalize(params[:content]), params[:format])
['sidebar', 'header', 'footer'].each do |subpage| ['sidebar', 'header', 'footer'].each do |subpage|
@page.send("set_#{subpage}".to_sym, params[subpage]) if params[subpage] @page.send("set_#{subpage}".to_sym, params[subpage]) if params[subpage]
end end
@@ -639,11 +642,6 @@ module Precious
end end
end end
def load_template(path)
template_page = wiki_page(::File.join(path, '_Template')).page || wiki_page('/_Template').page
template_page ? Gollum::TemplateFilter.apply_filters(template_page.raw_data) : nil
end
def update_wiki_page(wiki, page, content, commit, name = nil, format = nil) def update_wiki_page(wiki, page, content, commit, name = nil, format = nil)
return if !page || return if !page ||
((!content || page.raw_data == content) && page.format == format) ((!content || page.raw_data == content) && page.format == format)
@@ -0,0 +1 @@
{"files":{"app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js":{"logical_path":"app.js","mtime":"2020-08-03T18:13:54+02:00","size":136032,"digest":"6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd","integrity":"sha256-bpJeOKEqQMT6ngQAzIdOD0+Xtm/euQoUTepSfbtUT70="},"editor-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js":{"logical_path":"editor.js","mtime":"2020-08-03T18:13:54+02:00","size":747273,"digest":"b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708","integrity":"sha256-ssEPIu9soeEglWotEf9MoZrETX5yQPXMQ+yUkYTYtwg="},"app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css":{"logical_path":"app.css","mtime":"2020-03-30T11:12:22+02:00","size":298111,"digest":"b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7","integrity":"sha256-sgXlk6MPHMAFTi6e2fyK82WNjvSmK5cIwg8gRWDe77c="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2020-03-29T22:28:51+02:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2020-03-30T11:12:22+02:00","size":75,"digest":"512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb","integrity":"sha256-USSYw2i+DT+xuhBd+oQomuSDgOyfy++Ui9TiOwsJW/s="}},"assets":{"app.js":"app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js","editor.js":"editor-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js","app.css":"app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
@@ -1 +0,0 @@
{"files":{"app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js":{"logical_path":"app.js","mtime":"2021-03-23T08:40:11-07:00","size":136020,"digest":"0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838","integrity":"sha256-D9Io4mv75v4xotomjrDpjngMEZHBqRit84M3eUbpyDg="},"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js":{"logical_path":"editor.js","mtime":"2021-02-24T23:16:14-08:00","size":744866,"digest":"db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf","integrity":"sha256-2xDINRMG6S8ZJroiXQzZyOiGSCs7mCCoWCXsOrq18c8="},"app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css":{"logical_path":"app.css","mtime":"2021-03-23T08:40:11-07:00","size":396615,"digest":"ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2","integrity":"sha256-rUPKZLKV2ERLEPIu6GjxhCkmivSY8bxRVDSHi2kON6I="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2021-02-24T23:16:14-08:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2021-02-24T23:16:14-08:00","size":75,"digest":"512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb","integrity":"sha256-USSYw2i+DT+xuhBd+oQomuSDgOyfy++Ui9TiOwsJW/s="}},"assets":{"app.js":"app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js","editor.js":"editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js","app.css":"app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css","criticmarkup.css":"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css","print.css":"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css"}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,4 +7,3 @@
//= require gollum.placeholder //= require gollum.placeholder
//= require editor/sections //= require editor/sections
//= require jquery.resize //= require jquery.resize
//= require polyfills
@@ -156,10 +156,10 @@ $(document).ready(function() {
} }
if ($('.minibutton-upload-page').length) { if ($('#minibutton-upload-page').length) {
new ClipboardJS('#ClipboardJSlink'); new ClipboardJS('#ClipboardJSlink');
$('.minibutton-upload-page').parent().removeClass('jaws'); $('#minibutton-upload-page').parent().removeClass('jaws');
$('.minibutton-upload-page').click(function(e) { $('#minibutton-upload-page').click(function(e) {
e.preventDefault(); e.preventDefault();
$.GollumDialog.init({ $.GollumDialog.init({
@@ -213,9 +213,9 @@ $(document).ready(function() {
}); });
} }
if ($('.minibutton-rename-page').length) { if ($('#minibutton-rename-page').length) {
$('.minibutton-rename-page').parent().removeClass('jaws'); $('#minibutton-rename-page').parent().removeClass('jaws');
$('.minibutton-rename-page').click(function(e) { $('#minibutton-rename-page').click(function(e) {
e.preventDefault(); e.preventDefault();
var path = decodeURI(pagePath()); var path = decodeURI(pagePath());
@@ -257,9 +257,9 @@ $(document).ready(function() {
}); });
} }
if ($('.minibutton-new-page').length) { if ($('#minibutton-new-page').length) {
$('.minibutton-new-page').parent().removeClass('jaws'); $('#minibutton-new-page').parent().removeClass('jaws');
$('.minibutton-new-page').click(function(e) { $('#minibutton-new-page').click(function(e) {
e.preventDefault(); e.preventDefault();
var path = pagePath(); var path = pagePath();
if( path === undefined && $('#file-browser').length != 0 ){ if( path === undefined && $('#file-browser').length != 0 ){
@@ -345,7 +345,8 @@ $(document).ready(function() {
var formData = new FormData($('#gollum-editor-form').get(0)); var formData = new FormData($('#gollum-editor-form').get(0));
var paths = window.location.pathname.split('/'); var paths = window.location.pathname.split('/');
var sectionAnchor = window.location.hash.substr(1); var sectionAnchor = window.location.hash.substr(1);
formData.append('page', paths[ paths.length - 1 ] || '') formData.append('page', paths[ paths.length - 1 ] || '');
$.ajax({ $.ajax({
url: routePath('preview'), url: routePath('preview'),
data: formData, data: formData,
@@ -380,12 +381,8 @@ $(document).ready(function() {
active_tab = '#edit.tabnav-tab'; active_tab = '#edit.tabnav-tab';
} }
$('.tabnav-tab.selected').removeAttr('aria-current');
$('.tabnav-tab.selected').removeClass('selected'); $('.tabnav-tab.selected').removeClass('selected');
$(active_tab).attr('aria-current', 'page');
$(active_tab).addClass('selected'); $(active_tab).addClass('selected');
$('.tabnav-div').hide(); $('.tabnav-div').hide();
$(active_div).show(); $(active_div).show();
} }
@@ -1,6 +0,0 @@
// Polyfill to support Internet Explorer
if (!Array.prototype.includes) {
Array.prototype.includes = function (x) {
return 0 <= this.indexOf(x)
};
}
@@ -0,0 +1,83 @@
// Describes base page layout
/* @section wrapper */
#wiki-wrapper {
margin: 0 auto;
overflow: visible;
width: 100%;
@include desktop-breakpoint {
@include desktop-page-layout;
}
}
/* @section content */
#wiki-content {
height: 1%;
overflow: visible;
.wrap {
height: 1%;
overflow: auto;
}
&.uploading {
opacity: 0.5;
}
p, li {
code {
white-space:pre-wrap;
word-wrap:break-word;
}
}
}
/* @section body */
#wiki-body {
display: block;
width: 100%;
margin-right: 3%;
@include largemobile-breakpoint {
float: left;
clear: left;
.has-sidebar & {
width: $layout-with-sidebar - $layout-with-sidebar-leeway;
}
.has-leftbar & {
float: right;
clear: right;
}
}
}
/* @section sidebar */
#wiki-sidebar {
@include largemobile-breakpoint {
width: $layout-sidebar;
.has-leftbar & {
float: left;
}
.has-rightbar & {
float: right;
}
}
}
/* @section footer */
#wiki-footer {
clear: both;
@include largemobile-breakpoint {
.has-sidebar & {
width: $layout-with-sidebar;
}
}
}
@@ -147,3 +147,7 @@
} }
} }
} }
#gollum-dialog-dialog-buttons {
overflow: hidden;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -53,85 +53,19 @@ a {
/* Markdown body */ /* Markdown body */
.header-enum { .header-enum {
h2 {counter-reset: h3}
h3 {counter-reset: h4}
h4 {counter-reset: h5}
h5 {counter-reset: h6}
--header-enum-style: decimal; --header-enum-style: decimal;
h1 { h1:before {counter-increment: h1; content: counter(h1, var(--header-enum-style)) ". ";}
counter-increment: h1; h2:before {counter-increment: h2; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) ". ";}
counter-reset: h2; h3:before {counter-increment: h3; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) "." counter(h3, var(--header-enum-style)) ". ";}
h4:before {counter-increment: h4; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) "." counter(h3, var(--header-enum-style)) "." counter(h4, var(--header-enum-style)) ". ";}
&:before { h5:before {counter-increment: h5; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) "." counter(h3, var(--header-enum-style)) "." counter(h4, var(--header-enum-style)) "." counter(h5, var(--header-enum-style)) ". ";}
content: counter(h1, var(--header-enum-style)) ". "; h6:before {counter-increment: h6; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) "." counter(h3, var(--header-enum-style)) "." counter(h4, var(--header-enum-style)) "." counter(h5, var(--header-enum-style)) "." counter(h6, var(--header-enum-style)) ". ";}
}
}
h2 {
counter-increment: h2;
counter-reset: h3;
&:before {
content:
counter(h1, var(--header-enum-style))
"." counter(h2, var(--header-enum-style))
". ";
}
}
h3 {
counter-reset: h4;
counter-increment: h3;
&:before {
content:
counter(h1, var(--header-enum-style))
"." counter(h2, var(--header-enum-style))
"." counter(h3, var(--header-enum-style))
". ";
}
}
h4 {
counter-increment: h4;
counter-reset: h5;
&:before {
content:
counter(h1, var(--header-enum-style))
"." counter(h2, var(--header-enum-style))
"." counter(h3, var(--header-enum-style))
"." counter(h4, var(--header-enum-style))
". ";
}
}
h5 {
counter-increment: h5;
counter-reset: h6;
&:before {
content:
counter(h1, var(--header-enum-style))
"." counter(h2, var(--header-enum-style))
"." counter(h3, var(--header-enum-style))
"." counter(h4, var(--header-enum-style))
"." counter(h5, var(--header-enum-style))
". ";
}
}
h6 {
counter-increment: h6;
&:before {
content:
counter(h1, var(--header-enum-style))
"." counter(h2, var(--header-enum-style))
"." counter(h3, var(--header-enum-style))
"." counter(h4, var(--header-enum-style))
"." counter(h5, var(--header-enum-style))
"." counter(h6, var(--header-enum-style))
". ";
}
}
} }
#footer { #footer {
@@ -143,58 +77,43 @@ a {
padding: 1em 1em 1em 0; padding: 1em 1em 1em 0;
font-size: 15px; font-size: 15px;
line-height: 1.7; line-height: 1.7;
overflow: hidden;
word-wrap: break-word; word-wrap: break-word;
/* MediaWiki's TOC table -- this does not pertain to gollum's own TOC functionality */ /* MediaWiki's TOC table -- this does not pertain to gollum's own TOC functionality */
table.toc { table.toc {
width: auto; width: auto;
display: inline-table; display: inline-table;
.anchor { .anchor {
display: none; display: none;
} }
} }
h1, .anchor {
h2, display: inline-block;
h3, position: absolute;
h4, opacity: 0;
h5, background: url('data:image/svg+xml;utf8,<%= rocticon_css(:link) %>') no-repeat;
h6 { background-size: 0.6em 1.35em;
$anchor-icon-size: 20px; padding-right: 0.5em;
padding-top: 0.4em;
margin-left: -0.8em;
width: 1em;
height: 1em;
text-decoration: none;
transition-property: opacity;
transition: 0.1s;
}
position: relative; *:hover > .anchor, .anchor:focus{
opacity: 1;
}
.anchor { .anchor.edit {
display: inline-block; margin-left: 2em !important;
position: absolute; margin-top: 0.5em;
margin-top: 0.1em; height: 0.5em;
width: $anchor-icon-size; background: url('data:image/svg+xml;utf8,<%= rocticon_css(:pencil) %>') no-repeat;
text-decoration: none;
opacity: 0;
transition: opacity 0.1s ease-in-out;
&:before {
content: url('data:image/svg+xml;utf8,<%= rocticon_css(:link) %>');
}
&:not(.edit) {
left: -($anchor-icon-size/2);
}
&.edit {
margin-left: ($anchor-icon-size/2);
&:before {
content: url('data:image/svg+xml;utf8,<%= rocticon_css(:pencil) %>');
}
}
}
&:hover > .anchor,
.anchor:focus {
opacity: 1;
}
} }
a { a {
@@ -206,6 +125,13 @@ a {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
&:first-child {
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
padding-top: 0;
}
}
} }
> *:first-child { > *:first-child {
@@ -240,6 +166,18 @@ a {
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
h3 {
}
h4 {
}
h5 {
}
h6 {
}
p, blockquote, ul, ol, dl, table, pre { p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0; margin: 15px 0;
} }
@@ -677,10 +615,6 @@ a {
color: #999; color: #999;
background-color: #EAF2F5; background-color: #EAF2F5;
} }
.gg {
color: #000000a0;
}
} }
.type-csharp { .type-csharp {
@@ -712,15 +646,6 @@ div.pagination a.disabled {
pointer-events: none; pointer-events: none;
} }
nav.actions {
scrollbar-width: none;
-ms-overflow-style: -ms-autohiding-scrollbar;
::webkit-scrollbar {
display: none;
}
}
.search-results { .search-results {
.search-context li:nth-child(n+4) { .search-context li:nth-child(n+4) {
display: none; display: none;
+6 -8
View File
@@ -4,14 +4,12 @@
<h1 class="py-4">Create New Page</h1> <h1 class="py-4">Create New Page</h1>
</div> </div>
<div id="wiki-content" class="create edit"> <div id="wiki-content" class="create edit">
<div class="tabnav"> <div class="tabnav">
<nav class="tabnav-tabs" aria-label="Toggle edit or preview mode"> <nav class="tabnav-tabs" aria-label="Foo bar">
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page"> <a href="#" id="edit" class="tabnav-tab selected" aria-current="edit">Edit</a>
Edit <a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
</a> </nav>
<a href="#" id="preview" class="tabnav-tab">Preview</a> </div>
</nav>
</div>
<div class="has-sidebar tabnav-div" id="edit-content"> <div class="has-sidebar tabnav-div" id="edit-content">
{{>editor}} {{>editor}}
+2 -4
View File
@@ -5,10 +5,8 @@
</div> </div>
<div class="tabnav"> <div class="tabnav">
<nav class="tabnav-tabs"> <nav class="tabnav-tabs">
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page"> <a href="#" id="edit" class="tabnav-tab selected" aria-current="edit">Edit</a>
Edit <a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
</a>
<a href="#" id="preview" class="tabnav-tab">Preview</a>
</nav> </nav>
</div> </div>
<div class="tabnav-div" id="edit-content">{{>editor}}</div> <div class="tabnav-div" id="edit-content">{{>editor}}</div>
+3 -3
View File
@@ -37,7 +37,7 @@
<button class="btn btn-sm function-button" id="function-h3" title="Heading 3">h3</button> <button class="btn btn-sm function-button" id="function-h3" title="Heading 3">h3</button>
<span class="pr-2"></span> <span class="pr-2"></span>
<button class="btn btn-sm function-button" id="function-link" title="Link">{{#octicon}}link{{/octicon}}</button> <button class="btn btn-sm function-button" id="function-link" title="Link">{{#octicon}}link{{/octicon}}</button>
<button class="btn btn-sm function-button" id="function-image" title="Image">{{#octicon}}image{{/octicon}}</button> <button class="btn btn-sm function-button" id="function-image" title="Image">{{#octicon}}file-media{{/octicon}}</button>
<span class="pr-2"></span> <span class="pr-2"></span>
{{#critic_markup}} {{#critic_markup}}
<button class="btn btn-sm function-button" id="function-critic-accept" title="Accept Selected CriticMarkup">{{#octicon}}plus{{/octicon}}</button> <button class="btn btn-sm function-button" id="function-critic-accept" title="Accept Selected CriticMarkup">{{#octicon}}plus{{/octicon}}</button>
@@ -50,13 +50,13 @@
<div id="gollum-editor-format-selector"> <div id="gollum-editor-format-selector">
<label for="format">Keybinding</label> <label for="format">Keybinding</label>
<select id="keybinding" name="keybinding" class="form-select input-sm"> <select id="keybinding" name="keybinding" class="form-select">
<option selected="selected">default</option> <option selected="selected">default</option>
<option>vim</option> <option>vim</option>
<option>emacs</option> <option>emacs</option>
</select> </select>
<label for="format">Markup</label> <label for="format">Markup</label>
<select id="wiki_format" name="format" class="form-select input-sm"> <select id="wiki_format" name="format" class="form-select">
{{#formats}} {{#formats}}
{{#enabled}} {{#enabled}}
<option {{#selected}}selected="selected" {{/selected}}value="{{id}}" data-ext="{{ext}}"> <option {{#selected}}selected="selected" {{/selected}}value="{{id}}" data-ext="{{ext}}">
+1 -1
View File
@@ -13,7 +13,7 @@
<li class="Box-row Box-row--hover-gray border-top d-flex flex-items-center"> <li class="Box-row Box-row--hover-gray border-top d-flex flex-items-center">
<span class="float-left col-2" id="user-icons">{{>author_template}}</span> <span class="float-left col-2" id="user-icons">{{>author_template}}</span>
<span class="flex-auto col-1 text-gray-light">{{date}}</span> <span class="flex-auto col-1 text-gray-light">{{date}}</span>
<span class="flex-auto col-5">{{message}}<br/> <span class="flex-auto col-7">{{message}}<br/>
{{#files}} {{#files}}
<span class="flex-auto col-2">{{#renamed}}{{renamed}} -> {{/renamed}}<a href="{{link}}">{{file}}</a></span><br/> <span class="flex-auto col-2">{{#renamed}}{{renamed}} -> {{/renamed}}<a href="{{link}}">{{file}}</a></span><br/>
{{/files}} {{/files}}
+1
View File
@@ -11,6 +11,7 @@
{{#css}}<link rel="stylesheet" type="text/css" href="{{custom_css}}" media="all">{{/css}} {{#css}}<link rel="stylesheet" type="text/css" href="{{custom_css}}" media="all">{{/css}}
{{#noindex}}<meta name="robots" content="noindex, nofollow" />{{/noindex}} {{#noindex}}<meta name="robots" content="noindex, nofollow" />{{/noindex}}
<script> <script>
var criticMarkup = '{{critic_markup}}'; var criticMarkup = '{{critic_markup}}';
var baseUrl = '{{base_url}}'; var baseUrl = '{{base_url}}';
-72
View File
@@ -1,72 +0,0 @@
<details class="details-reset details-overlay">
<summary class="btn btn-invisible" aria-haspopup="true">
<span aria-label="Open menu">☰</span>
</summary>
<div class="SelectMenu mx-sm-2">
<div class="SelectMenu-modal">
<div class="SelectMenu-divider py-3">
<h2 class="h6">Current Page</h2>
<div>{{page_header}}</div>
</div>
{{#history}}
<a
class="SelectMenu-item"
href="{{history_path}}/{{escaped_url_path}}"
role="menuitem"
>
<span>History</span>
</a>
{{/history}}
{{#allow_editing}}
{{#allow_uploads}}
<a class="SelectMenu-item minibutton-upload-page" role="menuitem">
<span>Upload</span>
</a>
{{/allow_uploads}}
{{#editable}}
<a class="SelectMenu-item minibutton-rename-page" role="menuitem">
<span>Rename</span>
</a>
<a
class="SelectMenu-item minibutton-edit-page"
href="{{edit_path}}/{{escaped_url_path}}"
role="menuitem"
>
<span>Edit</span>
</a>
{{/editable}}
{{/allow_editing}}
<div class="SelectMenu-divider py-3">
<h2 class="h6">Main Menu</h2>
</div>
<div class="SelectMenu-list">
<a class="SelectMenu-item" role="menuitem" href="{{page_route}}">
Home
</a>
{{#overview}}
<a class="SelectMenu-item" role="menuitem" href="{{overview_path}}">
Overview
</a>
{{/overview}}
{{#latest_changes}}
<a
class="SelectMenu-item"
href="{{latest_changes_path}}"
role="menuitem"
>
Latest Changes
</a>
{{/latest_changes}}
</div>
</div>
</div>
</details>
+35 -95
View File
@@ -1,103 +1,43 @@
<nav class="TableObject actions pt-4 px-2 px-lg-0 overflow-x-scroll"> <nav class="actions pt-4">
<div class="TableObject-item hide-lg hide-xl">
{{>mobilenav}}
</div>
<div class="TableObject-item hide-sm hide-md"> <div class="TableObject">
<a class="btn btn-sm" id="minibutton-home" href="{{page_route}}"> <div class="TableObject-item">
Home <a class="btn" id="minibutton-home" href="{{page_route}}">Home</a>
</a> </div>
</div>
<div
class="TableObject-item TableObject-item--primary px-2"
{{^search}}style="visibility:hidden"{{/search}}
>
{{>searchbar}}
</div>
<div class="TableObject-item hide-sm hide-md"> <div class="TableObject-item TableObject-item--primary px-2" {{^search}}style="visibility:hidden"{{/search}}>
<div class="BtnGroup d-flex"> {{>searchbar}}
{{#overview}} </div>
<a
class="btn BtnGroup-item btn-sm"
href="{{overview_path}}"
id="minibutton-overview"
>
Overview
</a>
{{/overview}}
{{#latest_changes}} <div class="TableObject-item">
<a {{#overview}}<a class="btn" id="minibutton-overview" href="{{overview_path}}">Overview</a>{{/overview}}
class="btn BtnGroup-item btn-sm" {{#latest_changes}}<a class="btn" id="minibutton-latest-changes" href="{{latest_changes_path}}">Latest Changes</a>{{/latest_changes}}
href="{{latest_changes_path}}" </div>
id="minibutton-latest-changes"
>
Latest Changes
</a>
{{/latest_changes}}
</div>
</div>
<div class="TableObject-item px-2"> {{#history}}
<div class="BtnGroup d-flex"> <div class="TableObject-item pl-1">
{{#history}} <a class="btn" id="minibutton-history" href="{{history_path}}/{{escaped_url_path}}">Page History</a>
<a </div>
class="btn BtnGroup-item btn-sm hide-sm hide-md" {{/history}}
href="{{history_path}}/{{escaped_url_path}}"
id="minibutton-history"
>
History
</a>
{{/history}}
{{#allow_editing}} {{#allow_editing}}
{{#allow_uploads}} <div class="TableObject-item pl-1">
<button {{#allow_uploads}}
class="btn BtnGroup-item btn-sm hide-sm hide-md <a class="btn" id="minibutton-upload-page" href="#">Upload</a>
minibutton-upload-page" {{/allow_uploads}}
> {{#editable}}
Upload <a class="btn" id="minibutton-rename-page" href="#">Rename</a>
</button> <a class="btn" id="minibutton-edit-page" href="{{edit_path}}/{{escaped_url_path}}">Edit</a>
{{/allow_uploads}} <a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
{{/editable}}
{{^editable}}
{{#newable}}
<a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
{{/newable}}
{{/editable}}
</div>
{{/allow_editing}}
{{#editable}} </div>
<button
class="btn BtnGroup-item btn-sm hide-sm hide-md
minibutton-rename-page"
>
Rename
</button>
<a
class="btn BtnGroup-item btn-sm hide-sm hide-md"
href="{{edit_path}}/{{escaped_url_path}}"
id="minibutton-edit-page"
>
Edit
</a>
{{/editable}}
{{/allow_editing}}
</div>
</div>
{{#allow_editing}}
{{#editable}}
<div class="TableObject-item">
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
New
</a>
</div>
{{/editable}}
{{^editable}}
{{#newable}}
<div class="TableObject-item">
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
New
</a>
</div>
{{/newable}}
{{/editable}}
{{/allow_editing}}
</nav> </nav>
+1 -1
View File
@@ -18,7 +18,7 @@
<span class="pr-2">{{{icon}}}</span> <span class="pr-2">{{{icon}}}</span>
<span><a href="{{url}}">{{name}}</a></span> <span><a href="{{url}}">{{name}}</a></span>
{{#allow_editing}} {{#allow_editing}}
{{#is_file}}<button class="btn btn-sm float-right delete-file" data-file-path="{{file_path}}" data-confirm="Are you sure you want to delete {{name}}?">{{#octicon}}trash{{/octicon}}</button>{{/is_file}} {{#is_file}}<button class="btn btn-sm float-right delete-file" data-file-path="{{url}}" data-confirm="Are you sure you want to delete {{name}}?">{{#octicon}}trashcan{{/octicon}}</button>{{/is_file}}
{{/allow_editing}} {{/allow_editing}}
</li> </li>
{{/files_folders}} {{/files_folders}}
+15 -16
View File
@@ -1,14 +1,22 @@
<div id="wiki-content" class="px-2 px-lg-0"> <div id="wiki-content">
<h1 class="pt-4">{{page_header}}</h1> <h1 class="pt-4">{{page_header}}</h1>
<div class="breadcrumb">{{{breadcrumb}}}</div> <div class="breadcrumb">{{{breadcrumb}}}</div>
<div class="{{#has_header}}has-header{{/has_header}}{{#has_footer}} has-footer{{/has_footer}}{{#has_sidebar}} has-sidebar has-{{bar_side}}bar{{/has_sidebar}}{{#has_toc}} has-toc{{/has_toc}}"> <div class="{{#has_header}}has-header{{/has_header}}{{#has_footer}} has-footer{{/has_footer}}{{#has_sidebar}} has-sidebar has-{{bar_side}}bar{{/has_sidebar}}{{#has_toc}} has-toc{{/has_toc}}">
{{#has_toc}} {{#has_toc}}
<div id="wiki-toc-main"> <div id="wiki-toc-main">
{{{toc_content}}} {{{toc_content}}}
</div> </div>
{{/has_toc}} {{/has_toc}}
<div id="wiki-body" class="gollum-{{format}}-content"> {{#has_sidebar}}
<div id="wiki-sidebar" class="gollum-{{sidebar_format}}-content">
<div id="sidebar-content" class="Box Box--condensed col-3 markdown-body px-4 float-{{bar_side}}">
{{{sidebar_content}}}
</div>
</div>
{{/has_sidebar}}
<div id="wiki-body" class="gollum-{{format}}-content overflow-hidden {{#left_bar}}pl-4{{/left_bar}}">
{{#has_header}} {{#has_header}}
<div id="wiki-header" class="gollum-{{header_format}}-content"> <div id="wiki-header" class="gollum-{{header_format}}-content">
<div id="header-content" class="markdown-body"> <div id="header-content" class="markdown-body">
@@ -16,23 +24,14 @@
</div> </div>
</div> </div>
{{/has_header}} {{/has_header}}
<div class="main-content clearfix container-lg"> <div class="markdown-body {{#header_enum?}}header-enum{{/header_enum?}}" {{#header_enum?}}style="--header-enum-style:{{header_enum_style}};"{{/header_enum?}}>
<div class="markdown-body {{#header_enum?}}header-enum{{/header_enum?}} {{#has_sidebar}}float-md-{{body_side}} col-md-9{{/has_sidebar}}" {{#header_enum?}}style="--header-enum-style:{{header_enum_style}};"{{/header_enum?}}> {{{rendered_metadata}}}
{{{rendered_metadata}}} {{{content}}}
{{{content}}}
</div>
{{#has_sidebar}}
<div id="wiki-sidebar" class="Box Box--condensed float-md-{{body_side}} col-md-3">
<div id="sidebar-content" class="gollum-{{sidebar_format}}-content markdown-body px-4">
{{{sidebar_content}}}
</div>
</div>
{{/has_sidebar}}
</div> </div>
</div> </div>
{{#has_footer}} {{#has_footer}}
<div id="wiki-footer" class="gollum-{{footer_format}}-content my-2"> <div id="wiki-footer" class="gollum-{{footer_format}}-content">
<div id="footer-content" class="Box Box-condensed markdown-body px-4"> <div id="footer-content" class="Box Box-condensed markdown-body pl-2">
{{{footer_content}}} {{{footer_content}}}
</div> </div>
</div> </div>
+4 -11
View File
@@ -23,19 +23,12 @@ module Precious
end end
def files def files
files = @diff.force_encoding(Encoding::UTF_8).scan(%r{ files = @diff.split(%r{^diff --git a/.+ b/.+$}).reject(&:empty?)
^diff\ --git\ # diff start
.+? # diff body
(?=^diff\ --git|\Z) # scan until next diff or string
}sxmu)
files.map do |diff| files.map do |diff|
match = diff.match(%r{^diff --git (")?[ab]/(.+)(?(1)") (")?[ab]/(.+)(?(3)")}) matched = diff.match(%r{(?<=^--- a/).+$})
path = match[2] matched = diff.match(%r{(?<=^\+\+\+ b/).+$}) if matched.nil?
path = match[4] if path.nil?
{ {
path: path, path: matched[0],
lines: lines(diff) lines: lines(diff)
} }
end end
+7 -18
View File
@@ -19,21 +19,16 @@ module Precious
def lines(diff = @diff) def lines(diff = @diff)
lines = [] lines = []
lines_to_parse = diff.split("\n")[3..-1] lines_to_parse = diff.split("\n")[4..-1]
lines_to_parse = lines_to_parse[2..-1] if lines_to_parse[0] =~ /^(---|rename to )/ # If the diff is of a rename, the diff header will be one line longer than normal because it will contain a line starting with '+++' to indicate the 'new' filename.
# Make sure to skip that header line if it is present.
if lines_to_parse.nil? || lines_to_parse.empty? lines_to_parse = lines_to_parse[1..-1] if lines_to_parse[0].start_with?('+++')
lines_to_parse = [] # File is created without content
else
lines_to_parse = lines_to_parse[1..-1] if lines_to_parse[0].start_with?('+++')
end
lines_to_parse.each_with_index do |line, line_index| lines_to_parse.each_with_index do |line, line_index|
lines << { :line => line, lines << { :line => line,
:class => line_class(line), :class => line_class(line),
:ldln => left_diff_line_number(line), :ldln => left_diff_line_number(line),
:rdln => right_diff_line_number(line) } :rdln => right_diff_line_number(line) }
end end if diff
lines lines
end end
@@ -46,8 +41,6 @@ module Precious
def line_class(line) def line_class(line)
if line =~ /^@@/ if line =~ /^@@/
'gc' 'gc'
elsif git_line?(line)
'gg'
elsif line =~ /^\+/ elsif line =~ /^\+/
'gi' 'gi'
elsif line =~ /^\-/ elsif line =~ /^\-/
@@ -60,7 +53,7 @@ module Precious
@left_diff_line_number = nil @left_diff_line_number = nil
def left_diff_line_number(line) def left_diff_line_number(line)
if git_line?(line) if line =~ /^@@/
m, li = *line.match(/\-(\d+)/) m, li = *line.match(/\-(\d+)/)
@left_diff_line_number = li.to_i @left_diff_line_number = li.to_i
@current_line_number = @left_diff_line_number @current_line_number = @left_diff_line_number
@@ -82,7 +75,7 @@ module Precious
@right_diff_line_number = nil @right_diff_line_number = nil
def right_diff_line_number(line) def right_diff_line_number(line)
if git_line?(line) if line =~ /^@@/
m, ri = *line.match(/\+(\d+)/) m, ri = *line.match(/\+(\d+)/)
@right_diff_line_number = ri.to_i @right_diff_line_number = ri.to_i
@current_line_number = @right_diff_line_number @current_line_number = @right_diff_line_number
@@ -100,10 +93,6 @@ module Precious
end end
ret ret
end end
def git_line?(line)
!!(line =~ /^(\\ No newline|Binary files|@@)/)
end
end end
end end
end end
+1 -4
View File
@@ -61,10 +61,7 @@ module Precious
url.compact! url.compact!
return nil if url.empty? return nil if url.empty?
_url = ::File.join(*url) ::File.join(*url).gsub(%r{/{2,}}, '/')
_url.gsub!(%r{/{2,}}, '/')
_url.gsub!(%r{\?}, '%3F')
_url
end end
end end
+1 -1
View File
@@ -47,7 +47,7 @@ module Precious
end end
def mathjax_js def mathjax_js
"#{page_route('gollum/assets/mathjax/MathJax.js')}?config=TeX-AMS-MML_HTMLorMML" page_route("gollum/assets/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
end end
def css # custom css def css # custom css
+4 -5
View File
@@ -4,7 +4,6 @@ module Precious
module Views module Views
class Overview < Layout class Overview < Layout
attr_reader :results, :ref, :allow_editing, :newable attr_reader :results, :ref, :allow_editing, :newable
HIDDEN_PATHS = ['.gitkeep']
def title def title
"Overview of #{@ref}" "Overview of #{@ref}"
@@ -26,9 +25,9 @@ module Precious
title = crumb.basename title = crumb.basename
if title == path.basename if title == path.basename
breadcrumb << %{<li class="breadcrumb-item" aria-current="page">#{CGI.escapeHTML(title.to_s)}</li>} breadcrumb << %{<li class="breadcrumb-item" aria-current="page">#{title}</li>}
else else
breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{CGI.escapeHTML(title.to_s)}</a></li>} breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{title}</a></li>}
end end
end end
breadcrumb << %{</ol></nav>} breadcrumb << %{</ol></nav>}
@@ -52,9 +51,9 @@ module Precious
folder_path = @path ? "#{@path}/#{folder_name}" : folder_name folder_path = @path ? "#{@path}/#{folder_name}" : folder_name
folder_url = "#{overview_path}/#{folder_path}/" folder_url = "#{overview_path}/#{folder_path}/"
files_and_folders << {name: folder_name, icon: rocticon('file-directory'), type: 'dir', url: folder_url, is_file: false} files_and_folders << {name: folder_name, icon: rocticon('file-directory'), type: 'dir', url: folder_url, is_file: false}
elsif !HIDDEN_PATHS.include?(result_path) elsif result_path != '.gitkeep'
file_url = page_route(result.escaped_url_path) file_url = page_route(result.escaped_url_path)
files_and_folders << {name: result.filename, icon: rocticon('file'), type: 'file', url: file_url, file_path: result.escaped_url_path, is_file: true} files_and_folders << {name: result.filename, icon: rocticon('file'), type: 'file', url: file_url, is_file: true}
end end
end end
# 1012: Overview should list folders first, followed by files and pages sorted alphabetically # 1012: Overview should list folders first, followed by files and pages sorted alphabetically
+2 -5
View File
@@ -32,7 +32,7 @@ module Precious
path.descend do |crumb| path.descend do |crumb|
element = "#{crumb.basename}" element = "#{crumb.basename}"
next if element == @page.title next if element == @page.title
breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{CGI.escapeHTML(element.to_s)}</a></li>} breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{element}</a></li>}
end end
breadcrumb << %{</ol></nav>} breadcrumb << %{</ol></nav>}
breadcrumb.join("\n") breadcrumb.join("\n")
@@ -124,10 +124,6 @@ module Precious
@bar_side.to_s @bar_side.to_s
end end
def body_side
@bar_side == :right ? "left" : "right"
end
def left_bar def left_bar
@bar_side == :left @bar_side == :left
end end
@@ -268,6 +264,7 @@ module Precious
end end
result << "</tr>\n</table>\n" result << "</tr>\n</table>\n"
end end
end end
end end
end end
-1
View File
@@ -10,4 +10,3 @@ cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc
563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence <charles@charlespence.net> 1363478075 -0400 push 563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence <charles@charlespence.net> 1363478075 -0400 push
874f597a5659b4c3b153674ea04e406ff393975e 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e Nathan Lowe <techwiz96@gmail.com> 1421012322 -0500 push 874f597a5659b4c3b153674ea04e406ff393975e 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e Nathan Lowe <techwiz96@gmail.com> 1421012322 -0500 push
7bdfe65face6f7cf9877d8c1d8c1dd974a63745e f803c64d11407b23797325e3843f3f378b78f611 Dawa Ometto <dawa.ometto@phil.uu.nl> 1492034760 +0200 push 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e f803c64d11407b23797325e3843f3f378b78f611 Dawa Ometto <dawa.ometto@phil.uu.nl> 1492034760 +0200 push
f803c64d11407b23797325e3843f3f378b78f611 181c757cca395d4da18701d069a6b8123e88e040 ViChyavIn <nikita.vyach.ivanov@gmail.com> 1609841455 +0500 push
@@ -10,4 +10,3 @@ cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc
563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence <charles@charlespence.net> 1363478075 -0400 push 563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence <charles@charlespence.net> 1363478075 -0400 push
874f597a5659b4c3b153674ea04e406ff393975e 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e Nathan Lowe <techwiz96@gmail.com> 1421012322 -0500 push 874f597a5659b4c3b153674ea04e406ff393975e 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e Nathan Lowe <techwiz96@gmail.com> 1421012322 -0500 push
7bdfe65face6f7cf9877d8c1d8c1dd974a63745e f803c64d11407b23797325e3843f3f378b78f611 Dawa Ometto <dawa.ometto@phil.uu.nl> 1492034760 +0200 push 7bdfe65face6f7cf9877d8c1d8c1dd974a63745e f803c64d11407b23797325e3843f3f378b78f611 Dawa Ometto <dawa.ometto@phil.uu.nl> 1492034760 +0200 push
f803c64d11407b23797325e3843f3f378b78f611 181c757cca395d4da18701d069a6b8123e88e040 ViChyavIn <nikita.vyach.ivanov@gmail.com> 1609841455 +0500 push
+1 -1
View File
@@ -1 +1 @@
181c757cca395d4da18701d069a6b8123e88e040 f803c64d11407b23797325e3843f3f378b78f611
+2 -2
View File
@@ -474,7 +474,7 @@ EOF
end end
test "previews content" do test "previews content" do
post "/gollum/preview", :content => 'abc', :format => 'markdown', :page => 'Samewise Gamgee.mediawiki' post "/gollum/preview", :content => 'abc', :format => 'markdown', :page => 'Samewise%20Gamgee.mediawiki'
assert last_response.ok? assert last_response.ok?
assert last_response.body.include?('Samewise Gamgee</h1>') assert last_response.body.include?('Samewise Gamgee</h1>')
end end
@@ -953,7 +953,7 @@ context 'Frontend with base path' do
test 'base path mathjax assets' do test 'base path mathjax assets' do
get '/wiki/Home' get '/wiki/Home'
assert last_response.ok? assert last_response.ok?
assert last_response.body.include?('<script defer src="/wiki/gollum/assets/mathjax/MathJax.js?config=') assert last_response.body.include?('<script defer src="/wiki/gollum/assets/mathjax/MathJax.js')
end end
test 'compare view' do test 'compare view' do
-59
View File
@@ -1,59 +0,0 @@
# ~*~ encoding: utf-8 ~*~
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
require File.expand_path '../../lib/gollum/views/commit', __FILE__
def get_commit_diff(sha1)
commit = @wiki.repo.commit(sha1)
@wiki.repo.diff(commit.parent.id, sha1)
end
context "Precious::Views::Compare" do
setup do
@path = cloned_testpath('examples/lotr.git')
# Precious::App.set(:gollum_path, @path)
@wiki = Gollum::Wiki.new(@path)
end
test 'rename diff' do
# JGit returns differenly formatted diffs for rename commits. Support both kinds of diff.
jgit_diff = "diff --git a/Foo.md b/Bar.md\nsimilarity index 100%\nrename from Foo.md\nrename to Bar.md"
rugged_diff = "diff --git a/Bar.md b/Bar.md\nnew file mode 100644\nindex 0000000..e69de29\n--- /dev/null\n+++ b/Bar.md\n"
[jgit_diff, rugged_diff].each do |diff|
view = Precious::Views::Compare.new
view.instance_variable_set(:@diff, diff)
assert_equal [], view.lines
end
end
test 'file addition diff' do
view = Precious::Views::Compare.new
diff = get_commit_diff 'fbabba862dfa7ac35b39042dd4ad780c9f67b8cb'
view.instance_variable_set(:@diff, diff)
assert_equal [
{:line=>"@@ -0,0 +1 @@", :class=>"gc", :ldln=>"...", :rdln=>"..."},
{:line=>"+# Eye Of Sauron", :class=>"gi", :ldln=>" ", :rdln=>"1"}
], view.lines
end
test 'empty file addition diff' do
view = Precious::Views::Compare.new
diff = get_commit_diff '181c757cca395d4da18701d069a6b8123e88e040'
view.instance_variable_set(:@diff, diff)
assert_equal [], view.lines
end
test 'binary file addition diff' do
view = Precious::Views::Compare.new
diff = get_commit_diff 'afe2034d400ba21e13361f38f74900c51dbc7fde'
view.instance_variable_set(:@diff, diff)
lines = view.lines
line = lines[0].delete :line
assert_match %r{Binary files (/dev/null and b/Mordor/eye.jpg )?differ}, line
assert_equal [{:class=>"gg", :ldln=>"...", :rdln=>"..."}], lines
end
end
+2 -4
View File
@@ -35,11 +35,9 @@ context 'Precious::Views::LatestChanges' do
get(@url) get(@url)
body = last_response.body body = last_response.body
commits_list_elements = body.scan(%r{<li class="Box-row Box-row--hover-gray border-top d-flex flex-items-center">})
assert !commits_list_elements.nil?, "the commits should be listed with this tag"
assert commits_list_elements.length == 10, "/latest_changes should include the :pagination_count commit"
assert body.include?("Charles Pence</span>"), "/latest_changes should include Author Charles Pence" assert body.include?("Charles Pence</span>"), "/latest_changes should include Author Charles Pence"
assert body.include?('1db89eb'), "/latest_changes should include the :pagination_count commit"
assert !body.include?('a8ad3c0'), "/latest_changes should not include more than :pagination_count commits"
assert body.include?('<a href="/Data-Two.csv/874f597a5659b4c3b153674ea04e406ff393975e">Data-Two.csv</a>'), "/latest_changes include links to modified files in #{body}" assert body.include?('<a href="/Data-Two.csv/874f597a5659b4c3b153674ea04e406ff393975e">Data-Two.csv</a>'), "/latest_changes include links to modified files in #{body}"
assert body.include?('<a href="/Hobbit.md/874f597a5659b4c3b153674ea04e406ff393975e">Hobbit.md</a>'), "/latest_changes should include links to modified pages in #{body}" assert body.include?('<a href="/Hobbit.md/874f597a5659b4c3b153674ea04e406ff393975e">Hobbit.md</a>'), "/latest_changes should include links to modified pages in #{body}"
end end
-30
View File
@@ -44,23 +44,6 @@ context "Precious::Views::Overview" do
assert_equal "<nav aria-label=\"Breadcrumb\"><ol><li class=\"breadcrumb-item\"><a href=\"/gollum/overview\">Home</a></li>\n<li class=\"breadcrumb-item\"><a href=\"/gollum/overview/Mordor/\">Mordor</a></li>\n<li class=\"breadcrumb-item\"><a href=\"/gollum/overview/Mordor/Eye-Of-Sauron/\">Eye-Of-Sauron</a></li>\n<li class=\"breadcrumb-item\" aria-current=\"page\">Saruman</li>\n</ol></nav>", @page.breadcrumb assert_equal "<nav aria-label=\"Breadcrumb\"><ol><li class=\"breadcrumb-item\"><a href=\"/gollum/overview\">Home</a></li>\n<li class=\"breadcrumb-item\"><a href=\"/gollum/overview/Mordor/\">Mordor</a></li>\n<li class=\"breadcrumb-item\"><a href=\"/gollum/overview/Mordor/Eye-Of-Sauron/\">Eye-Of-Sauron</a></li>\n<li class=\"breadcrumb-item\" aria-current=\"page\">Saruman</li>\n</ol></nav>", @page.breadcrumb
end end
test "breadcrumbs guard against malicious filenames" do
malicious_path = '<script>alert("malicious-content");/Very Bad'
@page.instance_variable_set("@path", malicious_path)
@page.instance_variable_set("@base_url", "")
refute_includes @page.breadcrumb, malicious_path
assert_includes @page.breadcrumb, ">&lt;script&gt;alert(&quot;malicious-content&quot;);</a>"
end
test "breadcrumbs retain unicode and ASCII characters" do
title = "数学 📘"
@page.instance_variable_set("@path", title)
@page.instance_variable_set("@base_url", "")
assert_includes @page.breadcrumb, title
end
test "breadcrumb with no path" do test "breadcrumb with no path" do
assert_equal 'Home', @page.breadcrumb assert_equal 'Home', @page.breadcrumb
end end
@@ -89,17 +72,6 @@ context "Precious::Views::Overview" do
assert_equal result[:name], 'Orc' assert_equal result[:name], 'Orc'
end end
test "files_folders retain unicode and ASCII characters" do
@page.instance_variable_set("@path", "Mordor")
@page.instance_variable_set("@base_url", "")
@page.instance_variable_set("@results", [
FakePageResult.new("Mordor/Eye-Of-Sauron-👁️-数学.md")
])
result = @page.files_folders.first
assert result[:name], "Eye Of Sauron 👁️ 数学"
end
test "base url" do test "base url" do
# based on test "files_folders" # based on test "files_folders"
@page.instance_variable_set("@path", "Mordor") @page.instance_variable_set("@path", "Mordor")
@@ -107,7 +79,5 @@ context "Precious::Views::Overview" do
results = [FakePageResult.new("Mordor/Eye-Of-Sauron.md"), FakeFileResult.new("Mordor/Aragorn.pdf"), FakePageResult.new("Mordor/Orc/Saruman.md"), FakePageResult.new("Mordor/.gitkeep")] results = [FakePageResult.new("Mordor/Eye-Of-Sauron.md"), FakeFileResult.new("Mordor/Aragorn.pdf"), FakePageResult.new("Mordor/Orc/Saruman.md"), FakePageResult.new("Mordor/.gitkeep")]
@page.instance_variable_set("@results", results) @page.instance_variable_set("@results", results)
assert_equal @page.files_folders.first[:url], '/wiki/gollum/overview/Mordor/Orc/' assert_equal @page.files_folders.first[:url], '/wiki/gollum/overview/Mordor/Orc/'
assert_equal @page.files_folders.last[:url], '/wiki/Mordor/Eye-Of-Sauron'
assert_equal @page.files_folders.last[:file_path], 'Mordor/Eye-Of-Sauron'
end end
end end
+17 -115
View File
@@ -13,67 +13,6 @@ context "Precious::Views::Page" do
FileUtils.rm_rf(@path) FileUtils.rm_rf(@path)
end end
test "breadcrumbs guard against malicious input" do
malicious_path = '<script>alert("malicious-content");/Very Bad'
@wiki.write_page(malicious_path, :markdown, 'Is Bilbo a hobbit? Why certainly!')
page = @wiki.page(malicious_path)
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, false
refute_includes @view.breadcrumb, malicious_path
assert_includes @view.breadcrumb, ">&lt;script&gt;alert(&quot;malicious-content&quot;);</a>"
end
test "breadcrumbs retain unicode and ASCII characters" do
path = "数学 📘/Age of Bilbo"
@wiki.write_page(path, :markdown, "How old is Bilbo?")
page = @wiki.page(path)
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, false
assert_include @view.breadcrumb, "数学 📘"
end
test 'page <title> is the page header from content, if present' do
page_title = 'Page header from content'
@wiki.write_page(page_title, :markdown, 'Contents', commit_details)
@view = Precious::Views::Page.new.tap do |view|
view.instance_variable_set :@page, @wiki.page(page_title)
view.instance_variable_set :@h1_title, true
end
assert_equal @view.title, 'Page header from content'
end
test 'page <title> is URL path title if no h1 present' do
@wiki.write_page('dir/My path title', :markdown, 'Contents', commit_details)
page = @wiki.page('dir/My path title')
@view = Precious::Views::Page.new.tap do |view|
view.instance_variable_set :@page, page
view.instance_variable_set :@h1_title, false
end
assert_equal @view.title, 'My path title'
end
test "page header retains unicode and ASCII characters" do
title = "数学 📘"
@wiki.write_page(title, :markdown, "How old is Bilbo?")
page = @wiki.page(title)
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, false
assert @view.page_header, "数学 📘"
end
test "h1 title sanitizes correctly" do test "h1 title sanitizes correctly" do
title = 'H1' title = 'H1'
@wiki.write_page(title, :markdown, '# 1 & 2 <script>alert("js")</script>' + "\n # 3", commit_details) @wiki.write_page(title, :markdown, '# 1 & 2 <script>alert("js")</script>' + "\n # 3", commit_details)
@@ -85,46 +24,10 @@ context "Precious::Views::Page" do
@view.instance_variable_set :@h1_title, true @view.instance_variable_set :@h1_title, true
# Test page_header_from_content(@content) # Test page_header_from_content(@content)
assert @view.page_header, "1 & 2" actual = @view.title
assert_equal '1 & 2', actual
end end
test "page header uses filename when h1_title is false" do
title = "H1"
contents = <<~TEXT
# First H1 header
# Second H1 header
TEXT
@wiki.write_page(title, :markdown, contents, commit_details)
page = @wiki.page(title)
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, false
assert_equal @view.page_header, "H1"
end
test "page header uses filename when h1_title is true" do
contents = <<~TEXT
# First H1 header
# Second H1 header
TEXT
@wiki.write_page("H1", :markdown, contents, commit_details)
page = @wiki.page("H1")
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, true
assert_equal @view.page_header, "First H1 header"
end
test "metadata is rendered into a table" do test "metadata is rendered into a table" do
title = 'metadata test' title = 'metadata test'
@wiki.write_page(title, :markdown, "---\nsome: metadata\nhere: for you\n---\n# Some markdown\nIn this doc") @wiki.write_page(title, :markdown, "---\nsome: metadata\nhere: for you\n---\n# Some markdown\nIn this doc")
@@ -190,6 +93,21 @@ EOS
assert_equal "594e928cc5dcb6d833dfb86bb36076fd4a84eea7", @view.id assert_equal "594e928cc5dcb6d833dfb86bb36076fd4a84eea7", @view.id
end end
test "h1 title can be disabled" do
title = 'H1'
@wiki.write_page(title, :markdown, '# 1 & 2 <script>alert("js")</script>' + "\n # 3", commit_details)
page = @wiki.page(title)
@view = Precious::Views::Page.new
@view.instance_variable_set :@page, page
@view.instance_variable_set :@content, page.formatted_data
@view.instance_variable_set :@h1_title, false
# Title is based on file name when h1_title is false.
actual = @view.title
assert_equal title, actual
end
test "breadcrumbs" do test "breadcrumbs" do
@wiki.write_page('subdir/BC Test 1', :markdown, 'Test', commit_details) @wiki.write_page('subdir/BC Test 1', :markdown, 'Test', commit_details)
page = @wiki.page('subdir/BC Test 1') page = @wiki.page('subdir/BC Test 1')
@@ -209,20 +127,4 @@ EOS
@view.instance_variable_set :@content, page.formatted_data @view.instance_variable_set :@content, page.formatted_data
assert_equal @view.breadcrumb, '' assert_equal @view.breadcrumb, ''
end end
test "body_side is 'right' by default" do
@view = Precious::Views::Page.new
assert_equal @view.body_side, "right"
end
test "body_side is 'left' if bar_side side is 'right'" do
@view = Precious::Views::Page.new
@view.instance_variable_set :@bar_side, :right
assert_equal @view.body_side, "left"
end
test "links to pages containing ?" do
@view = Precious::Views::Page.new
assert_equal @view.page_route("Page?"), '/Page%3F'
end
end end