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
79 changed files with 435 additions and 1383 deletions
-39
View File
@@ -1,39 +0,0 @@
name: Deploy docker
on: [push]
env:
DEPLOY_NAME: gollumwiki/gollum:latest
jobs:
build:
runs-on: ubuntu-latest
if: ${{ github.ref == 'refs/heads/master' }}
steps:
- name: Check Out Repo
uses: actions/checkout@v2
- name: Login
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Cache docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: ./
file: ./Dockerfile
builder: ${{ steps.buildx.outputs.name }}
push: true
tags: ${{ env.DEPLOY_NAME }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
-38
View File
@@ -1,38 +0,0 @@
name: Build and Test Docker
on: [push, pull_request]
env:
CI_IMAGE: gollum-ci-img
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v2
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Cache docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build
id: docker_build
uses: docker/build-push-action@v2
with:
context: ./
file: ./Dockerfile
builder: ${{ steps.buildx.outputs.name }}
push: false
tags: ${{ env.CI_IMAGE }}
outputs: type=docker
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- name: docker state
run: docker image ls
- name: Run tests
run: docker run -e CI=true -w /app --entrypoint bundle ${{ env.CI_IMAGE }} exec rake
-25
View File
@@ -1,25 +0,0 @@
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Create Release
jobs:
build:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
-29
View File
@@ -1,29 +0,0 @@
name: Ruby Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
ruby: [2.4.0, 2.6.0, 3.0.0, jruby-9.2.18.0]
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v2
- run: echo "The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '11'
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: exec rake
run: bundle exec rake
-1
View File
@@ -8,4 +8,3 @@ Gemfile.lock
.* .*
!.sprockets* !.sprockets*
!lib/gollum/public/gollum/stylesheets/_styles.css !lib/gollum/public/gollum/stylesheets/_styles.css
!.github*
+9
View File
@@ -0,0 +1,9 @@
rvm:
- 2.4.0
- 2.6.0
- jruby-9.2.9.0
jdk:
- oraclejdk9
before_install:
- sudo apt-get update
- sudo apt-get install libicu-dev
+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 .
-29
View File
@@ -1,29 +0,0 @@
FROM ruby:2.7
ENV DEBIAN_FRONTEND="noninteractive"
RUN apt-get update && apt-get install -y \
libicu-dev \
cmake
COPY Gemfile* /tmp/
COPY gollum.gemspec* /tmp/
WORKDIR /tmp
RUN bundle install
RUN gem install \
asciidoctor \
creole \
wikicloth \
org-ruby \
RedCloth \
bibtex-ruby \
&& echo "gem-extra complete"
WORKDIR /app
COPY . /app
RUN bundle exec rake install
VOLUME /wiki
WORKDIR /wiki
COPY docker-run.sh /docker-run.sh
ENTRYPOINT ["/docker-run.sh"]
+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
+8 -12
View File
@@ -2,10 +2,10 @@ 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://github.com/gollum/gollum/actions/workflows/test.yaml/badge.svg) [![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.
@@ -46,7 +46,7 @@ Installation examples for individual systems can be seen [here](https://github.c
To run, simply: To run, simply:
1. Run: `gollum /path/to/wiki` where `/path/to/wiki` is an initialized Git repository. 1. Run: `gollum /path/to/wiki`.
2. Open `http://localhost:4567` in your browser. 2. Open `http://localhost:4567` in your browser.
See [below](#running-from-source) for information on running Gollum from source, as a Rack app, and more. See [below](#running-from-source) for information on running Gollum from source, as a Rack app, and more.
@@ -84,19 +84,19 @@ See [here](https://github.com/gollum/gollum/wiki/Custom-rendering-gems) for inst
### Rack ### Rack
Gollum can also be run with any [rack-compatible web server](https://github.com/rack/rack#supported-web-servers). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack). Gollum can also be ran with any [rack-compatible web server](https://github.com/rack/rack#supported-web-servers). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack).
### Rack, with an authentication server ### Rack, with an authentication server
Gollum can also be run alongside a CAS (Central Authentication Service) SSO (single sign-on) server. With a bit of tweaking, this adds basic user-support to Gollum. To see an example and an explanation, navigate [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack-and-CAS-SSO). Gollum can also be ran alongside a CAS (Central Authentication Service) SSO (single sign-on) server. With a bit of tweaking, this adds basic user-support to Gollum. To see an example and an explanation, navigate [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Rack-and-CAS-SSO).
### Docker ### Docker
Gollum can also be run via [Docker](https://www.docker.com/). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Docker). Gollum can also be ran via [Docker](https://www.docker.com/). More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-via-Docker).
### Service ### Service
Gollum can also be run as a service. More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-as-a-service). Gollum can also be ran as a service. More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-as-a-service).
## CONFIGURATION ## CONFIGURATION
@@ -126,7 +126,7 @@ Gollum comes with the following command line options:
| --no-display-metadata | none | Do not render metadata tables in pages. | | --no-display-metadata | none | Do not render metadata tables in pages. |
| --user-icons | [MODE] | Tell Gollum to use specific user icons for history view. Can be set to `gravatar`, `identicon` or `none`. Default: `none`. | | --user-icons | [MODE] | Tell Gollum to use specific user icons for history view. Can be set to `gravatar`, `identicon` or `none`. Default: `none`. |
| --mathjax-config | [FILE] | Specify path to a custom MathJax configuration. If not specified, uses the `mathjax.config.js` file from repository root. | | --mathjax-config | [FILE] | Specify path to a custom MathJax configuration. If not specified, uses the `mathjax.config.js` file from repository root. |
| --template-dir | [PATH] | Specify custom mustache template directory. Only overrides templates that exist in this directory. | | --template-dir | [PATH] | Specify custom mustache template directory. |
| --template-page | none | Use _Template in root as a template for new pages. Must be committed. | | --template-page | none | Use _Template in root as a template for new pages. Must be committed. |
| --emoji | none | Parse and interpret emoji tags (e.g. `:heart:`) except when the leading colon is backslashed (e.g. `\:heart:`). | | --emoji | none | Parse and interpret emoji tags (e.g. `:heart:`) except when the leading colon is backslashed (e.g. `\:heart:`). |
| --lenient-tag-lookup | none | 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. | | --lenient-tag-lookup | none | 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. |
@@ -150,7 +150,3 @@ When `--config` option is used, certain inner parts of Gollum can be customized.
## CONTRIBUTING ## CONTRIBUTING
Please consider helping out! See [CONTRIBUTING](CONTRIBUTING.md) for information on how to submit issues, and how to start hacking on gollum. Please consider helping out! See [CONTRIBUTING](CONTRIBUTING.md) for information on how to submit issues, and how to start hacking on gollum.
## THANKS TO
[![Testing Powered By SauceLabs](https://opensource.saucelabs.com/images/opensauce/powered-by-saucelabs-badge-gray.png?sanitize=true "Testing Powered By SauceLabs")](https://saucelabs.com)
+3 -2
View File
@@ -149,10 +149,10 @@ MSG
'Can be set to \'gravatar\' or \'identicon\'. Default: standard avatar.') do |mode| 'Can be set to \'gravatar\' or \'identicon\'. Default: standard avatar.') do |mode|
wiki_options[:user_icons] = mode.to_s wiki_options[:user_icons] = mode.to_s
end end
opts.on('--template-dir [PATH]', 'Specify custom mustache template directory. Only overrides templates that exist in this 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
@@ -271,6 +271,7 @@ else
Precious::App.set(:environment, ENV.fetch('RACK_ENV', :production).to_sym) Precious::App.set(:environment, ENV.fetch('RACK_ENV', :production).to_sym)
Precious::App.set(:gollum_path, gollum_path) Precious::App.set(:gollum_path, gollum_path)
Precious::App.set(:wiki_options, wiki_options) Precious::App.set(:wiki_options, wiki_options)
Precious::App.settings.mustache[:templates] = wiki_options[:template_dir] if wiki_options[:template_dir]
if cfg = options[:config] if cfg = options[:config]
# If the path begins with a '/' it will be considered an absolute path, # If the path begins with a '/' it will be considered an absolute path,
-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
-9
View File
@@ -1,9 +0,0 @@
#!/bin/bash
# Initialize the wiki
if [ ! -d .git ]; then
git init
fi
# Start gollum service
gollum --mathjax
+17 -20
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,23 +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.1', '< 2' 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_dependency 'i18n', '~> 1.8'
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'
@@ -47,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[
@@ -60,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
@@ -70,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
@@ -1176,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
@@ -1204,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
+13 -16
View File
@@ -5,35 +5,32 @@ require 'digest/sha1'
require 'ostruct' require 'ostruct'
# external # external
require 'i18n'
require 'github/markup' require 'github/markup'
require 'rhino' if RUBY_PLATFORM == 'java' require 'rhino' if RUBY_PLATFORM == 'java'
# internal # internal
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'
::I18n.available_locales = [:en]
::I18n.load_path = Dir[::File.expand_path("lib/gollum/locales") + "/*.yml"]
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 end
def self.apply_filters(data) class DuplicatePageError < Error
@@filters.each do |pattern, replacement| attr_accessor :dir
data.gsub!(pattern, replacement.call) attr_accessor :existing_path
end attr_accessor :attempted_path
data
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
end end
+16 -24
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'
@@ -15,14 +14,12 @@ require 'pathname'
require 'gollum' require 'gollum'
require 'gollum/assets' require 'gollum/assets'
require 'gollum/views/helpers' require 'gollum/views/helpers'
require 'gollum/views/helpers/locale_helpers'
require 'gollum/views/layout' require 'gollum/views/layout'
require 'gollum/views/editable' require 'gollum/views/editable'
require 'gollum/views/has_page' require 'gollum/views/has_page'
require 'gollum/views/has_user_icons' require 'gollum/views/has_user_icons'
require 'gollum/views/pagination' require 'gollum/views/pagination'
require 'gollum/views/rss.rb' require 'gollum/views/rss.rb'
require 'gollum/views/template_cascade'
require File.expand_path '../helpers', __FILE__ require File.expand_path '../helpers', __FILE__
@@ -72,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)
@@ -111,11 +106,7 @@ module Precious
@wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki') @wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki')
forbid unless @allow_editing || request.request_method == 'GET' forbid unless @allow_editing || request.request_method == 'GET'
Precious::App.set(:mustache, {:templates => settings.wiki_options[:template_dir]}) if settings.wiki_options[:template_dir]
if settings.wiki_options[:template_dir]
Precious::Views::Layout.extend Precious::Views::TemplateCascade
Precious::Views::Layout.template_priority_path = settings.wiki_options[:template_dir]
end
@base_url = url('/', false).chomp('/').force_encoding('utf-8') @base_url = url('/', false).chomp('/').force_encoding('utf-8')
@page_dir = settings.wiki_options[:page_file_dir].to_s @page_dir = settings.wiki_options[:page_file_dir].to_s
@@ -126,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')
@@ -312,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?
@@ -328,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
@@ -361,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)
@@ -423,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
@@ -645,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.text_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-f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5.js":{"logical_path":"app.js","mtime":"2021-07-10T00:40:20+09:00","size":136040,"digest":"f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5","integrity":"sha256-8FQB7jdPDH9I/CvAjjC09NtwWGH9WJXtcJmGg7ODv7U="},"editor-9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a.js":{"logical_path":"editor.js","mtime":"2021-07-10T00:42:29+09:00","size":744886,"digest":"9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a","integrity":"sha256-mIHQx65mMpPw46fnJynux+lA+mExhcB2cJt20pL1cDo="},"app-cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694.css":{"logical_path":"app.css","mtime":"2021-07-10T00:39:36+09:00","size":396625,"digest":"cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694","integrity":"sha256-yxIrTBdQD6peATy0MzT6/PLdfXL2lLBtlhb4sz/vtpQ="},"criticmarkup-31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4.css":{"logical_path":"criticmarkup.css","mtime":"2021-07-08T05:19:03+09:00","size":646,"digest":"31ae5d3282bbb8e7b7c3c9917e9fb68e3315a6b4a75da6cec48d21b8846905c4","integrity":"sha256-Ma5dMoK7uOe3w8mRfp+2jjMVprSnXabOxI0huIRpBcQ="},"print-512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb.css":{"logical_path":"print.css","mtime":"2021-07-08T05:19:03+09:00","size":75,"digest":"512498c368be0d3fb1ba105dfa84289ae48380ec9fcbef948bd4e23b0b095bfb","integrity":"sha256-USSYw2i+DT+xuhBd+oQomuSDgOyfy++Ui9TiOwsJW/s="}},"assets":{"app.js":"app-f05401ee374f0c7f48fc2bc08e30b4f4db705861fd5895ed70998683b383bfb5.js","editor.js":"editor-9881d0c7ae663293f0e3a7e72729eec7e940fa613185c076709b76d292f5703a.js","app.css":"app-cb122b4c17500faa5e013cb43334fafcf2dd7d72f694b06d9616f8b33fefb694.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
@@ -218,7 +218,7 @@
$form.attr('action', this.href || routePath('preview')); $form.attr('action', this.href || routePath('preview'));
$form.attr('target', '_blank'); $form.attr('target', '_blank');
var paths = window.location.pathname.split('/'); var paths = window.location.pathname.split('/');
$form.attr('page', decodeURIComponent(paths[ paths.length - 1 ]) || '') $form.attr('page', paths[ paths.length - 1 ] || '')
$form.submit(); $form.submit();
@@ -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', decodeURIComponent(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;
}
@@ -29,7 +29,6 @@ a.tabnav-tab:focus {
overflow: hidden; overflow: hidden;
font-family: Consolas, "Liberation Mono", Courier, monospace; font-family: Consolas, "Liberation Mono", Courier, monospace;
font-size: 1em; font-size: 1em;
padding: 0;
} }
#gollum-editor { #gollum-editor {
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,
h2,
h3,
h4,
h5,
h6 {
$anchor-icon-size: 20px;
position: relative;
.anchor { .anchor {
display: inline-block; display: inline-block;
position: absolute; position: absolute;
margin-top: 0.1em;
width: $anchor-icon-size;
text-decoration: none;
opacity: 0; opacity: 0;
transition: opacity 0.1s ease-in-out; background: url('data:image/svg+xml;utf8,<%= rocticon_css(:link) %>') no-repeat;
background-size: 0.6em 1.35em;
&:before { padding-right: 0.5em;
content: url('data:image/svg+xml;utf8,<%= rocticon_css(:link) %>'); padding-top: 0.4em;
margin-left: -0.8em;
width: 1em;
height: 1em;
text-decoration: none;
transition-property: opacity;
transition: 0.1s;
} }
&:not(.edit) { *:hover > .anchor, .anchor:focus{
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; opacity: 1;
} }
.anchor.edit {
margin-left: 2em !important;
margin-top: 0.5em;
height: 0.5em;
background: url('data:image/svg+xml;utf8,<%= rocticon_css(:pencil) %>') no-repeat;
} }
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;
+3 -5
View File
@@ -5,11 +5,9 @@
</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>
<a href="#" id="preview" class="tabnav-tab">Preview</a>
</nav> </nav>
</div> </div>
+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>
+21 -81
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 class="TableObject">
<div class="TableObject-item">
<a class="btn" id="minibutton-home" href="{{page_route}}">Home</a>
</div> </div>
<div class="TableObject-item hide-sm hide-md">
<a class="btn btn-sm" id="minibutton-home" href="{{page_route}}">
Home
</a>
</div>
<div <div class="TableObject-item TableObject-item--primary px-2" {{^search}}style="visibility:hidden"{{/search}}>
class="TableObject-item TableObject-item--primary px-2"
{{^search}}style="visibility:hidden"{{/search}}
>
{{>searchbar}} {{>searchbar}}
</div> </div>
<div class="TableObject-item hide-sm hide-md"> <div class="TableObject-item">
<div class="BtnGroup d-flex"> {{#overview}}<a class="btn" id="minibutton-overview" href="{{overview_path}}">Overview</a>{{/overview}}
{{#overview}} {{#latest_changes}}<a class="btn" id="minibutton-latest-changes" href="{{latest_changes_path}}">Latest Changes</a>{{/latest_changes}}
<a
class="btn BtnGroup-item btn-sm"
href="{{overview_path}}"
id="minibutton-overview"
>
Overview
</a>
{{/overview}}
{{#latest_changes}}
<a
class="btn BtnGroup-item btn-sm"
href="{{latest_changes_path}}"
id="minibutton-latest-changes"
>
Latest Changes
</a>
{{/latest_changes}}
</div>
</div> </div>
<div class="TableObject-item px-2">
<div class="BtnGroup d-flex">
{{#history}} {{#history}}
<a <div class="TableObject-item pl-1">
class="btn BtnGroup-item btn-sm hide-sm hide-md" <a class="btn" id="minibutton-history" href="{{history_path}}/{{escaped_url_path}}">Page History</a>
href="{{history_path}}/{{escaped_url_path}}" </div>
id="minibutton-history"
>
History
</a>
{{/history}} {{/history}}
{{#allow_editing}} {{#allow_editing}}
<div class="TableObject-item pl-1">
{{#allow_uploads}} {{#allow_uploads}}
<button <a class="btn" id="minibutton-upload-page" href="#">Upload</a>
class="btn BtnGroup-item btn-sm hide-sm hide-md
minibutton-upload-page"
>
Upload
</button>
{{/allow_uploads}} {{/allow_uploads}}
{{#editable}} {{#editable}}
<button <a class="btn" id="minibutton-rename-page" href="#">Rename</a>
class="btn BtnGroup-item btn-sm hide-sm hide-md <a class="btn" id="minibutton-edit-page" href="{{edit_path}}/{{escaped_url_path}}">Edit</a>
minibutton-rename-page" <a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
>
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}} {{/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}} {{^editable}}
{{#newable}} {{#newable}}
<div class="TableObject-item"> <a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
<a class="btn btn-primary btn-sm minibutton-new-page" href="#">
New
</a>
</div>
{{/newable}} {{/newable}}
{{/editable}} {{/editable}}
</div>
{{/allow_editing}} {{/allow_editing}}
</div>
</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}}
+13 -14
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> </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>
{{#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
+6 -17
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 = [] # File is created without content
else
lines_to_parse = lines_to_parse[1..-1] if lines_to_parse[0].start_with?('+++') 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,82 +0,0 @@
module Precious
module Views
module LocaleHelpers
NO_METHOD_MESSAGE = 'Argument must be a view method'
YAML_VARIABLE_REGEXP = /\%\{[\w]+\}/
# Returns all I18n translation strings for the current view class.
# This method support YAML arguments. For example:
#
# last_edited: This content was last edited at %{date}.
#
# Where the `date` argument must be a method available on the current
# class.
#
# Use this interface within Mustache templates to render any user
# interface strings in the current locale. For example:
#
# {{ t.last_edited }}
#
def t
autofill I18n.t(locale_klass_name)
end
private
# Recursively looks up I18n translation values and autofills any YAML
# arguments with the return value of the current class's matching method.
#
# When a translation value with an argument has no matching method, we
# then return that value transformed to include the `no_method_message`
#
def autofill(yaml)
yaml.map { |i18n_key, i18n_value|
if i18n_value.is_a? Hash
[i18n_key, autofill(i18n_value)]
elsif has_arguments?(i18n_value)
fill_argument_content(i18n_key, i18n_value)
else
[i18n_key, i18n_value]
end
}.to_h
end
def fill_argument_content(i18n_key, i18n_value)
i18n_value.gsub!(YAML_VARIABLE_REGEXP) do |argument|
method_name = argument.gsub(/[^\w]/, '')
next if method_name.nil?
begin
self.public_send(method_name)
rescue NoMethodError => error
no_method_message(method_name)
end
end
[i18n_key, i18n_value]
end
def has_arguments?(i18n_value)
i18n_value.match?(YAML_VARIABLE_REGEXP)
end
# Returns the current class name in a format that is acceptable in YAML.
# To summarize its function:
#
# NameOfConstant => name_of_constant
#
def locale_klass_name
@locale_klass_name ||= self.class.name.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr('-', '_').
downcase
end
def no_method_message(method_name, message = NO_METHOD_MESSAGE)
"[#{message}: #{method_name}]"
end
end
end
end
+1 -2
View File
@@ -6,7 +6,6 @@ module Precious
include Rack::Utils include Rack::Utils
include Sprockets::Helpers include Sprockets::Helpers
include Precious::Views::AppHelpers include Precious::Views::AppHelpers
include Precious::Views::LocaleHelpers
include Precious::Views::SprocketsHelpers include Precious::Views::SprocketsHelpers
include Precious::Views::RouteHelpers include Precious::Views::RouteHelpers
include Precious::Views::OcticonHelpers include Precious::Views::OcticonHelpers
@@ -48,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
-36
View File
@@ -1,36 +0,0 @@
module Precious
module Views
module TemplateCascade
def template_priority_path
@@template_priority_path
end
def template_priority_path=(path)
@@template_priority_path = File.expand_path(path)
@template = nil
end
def first_path_available(name)
priority = File.join(template_priority_path, "#{name}.#{template_extension}")
default = File.join(template_path, "#{name}.#{template_extension}")
File.exists?(priority) ? priority : default
end
# Method should track lib/mustache/settings.rb from Mustache project.
def template_file
@template_file || first_path_available(template_name)
end
# Method should track lib/mustache.rb from Mustache project.
def partial(name)
path = first_path_available(name)
begin
File.read(path)
rescue
raise if raise_on_context_miss?
""
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
@@ -1,8 +0,0 @@
<nav>
<div style="background-color: red;">NAVBAR_OVERRIDE</div>
<p>Still include an original partial to ensure the fallback works even when nested from an overriden partial:</p>
<div>
{{>mobilenav}}
</div>
</nav>
@@ -1,12 +0,0 @@
<div id="wiki-wrapper" class="page">
<p>Include an overridden partial:</p>
<div id="head">
{{#navbar?}}{{>navbar}}{{/navbar?}}
</div>
<div style="background-color: red;">PAGE_OVERRIDE</div>
{{>wiki_content}}
</div>
-134
View File
@@ -1,134 +0,0 @@
require_relative "../../helper"
require_relative "../../../lib/gollum/views/helpers"
describe Precious::Views::LocaleHelpers do
class TestClass < Mustache
include Precious::Views::LocaleHelpers
def author
"J.R.R."
end
def location
"Bloemfontein"
end
end
def setup
::I18n.available_locales = [:en, :de]
::I18n.load_path = Dir[File.expand_path("test/support/locales" + "/*.yml")]
end
def teardown
I18n.locale = :en
end
let(:dummy_instance) { TestClass.new }
describe "#t" do
describe "mustache usage" do
let(:subject) { dummy_instance.render(mustache_template) }
let(:mustache_template) { "{{ t.hello_world }}" }
describe "in the default locale" do
it "returns the translation string" do
_(subject).must_equal "Hello world"
end
end
describe "in the configured locale" do
it "returns the translation string" do
I18n.locale = :de
_(subject).must_equal "Hallo Welt"
end
end
describe "translations with YAML arguments" do
let(:mustache_template) { "{{ t.author_info.full }}" }
describe "in the default locale" do
it "autofills YAML arguments" do
_(subject).must_equal "Author J.R.R. is from Bloemfontein"
end
end
describe "in the configured locale" do
it "autofills YAML arguments" do
I18n.locale = :de
_(subject).must_equal "Autor J.R.R. ist vom Bloemfontein"
end
end
end
describe "translations with invalid arguments" do
let(:mustache_template) { "{{ t.has_invalid_argument }}" }
it "fails gracefully with embedded error message" do
expected_string = "Welcome to " \
"[#{TestClass::NO_METHOD_MESSAGE}: no_matching_method]"
_(subject).must_equal expected_string
end
end
describe "out of scope translations" do
let(:mustache_template) { "{{ t.never_called }}" }
it "does not include translation keys from other classes" do
_(subject).must_be_empty
end
end
describe "missing translations" do
let(:mustache_template) { "{{ t.nested.nonexistent_key }}" }
it "outputs an empty string" do
_(subject).must_be_empty
end
end
end
describe "usage" do
let(:subject) { dummy_instance.t }
it "returns a hash" do
_(subject).must_be_kind_of Hash
end
it "returns translation keys under 'test_class'" do
i18n_keys = I18n.t("test_class").keys
_(subject.keys).must_equal i18n_keys
end
it "does not return translation keys under other classes" do
other_i18n_keys = I18n.t("nonexistant_test_class").keys
_(subject.keys).wont_include other_i18n_keys
end
it "returns nested keys" do
nested_keys = subject[:author_info].keys
_(nested_keys).must_equal [:full]
end
describe "auto-filled YAML arguments" do
let(:subject) { dummy_instance.t[:author_info][:full] }
it "auto-fills in the default locale" do
_(subject).must_equal "Author J.R.R. is from Bloemfontein"
end
it "auto-fills in a configured locale" do
I18n.locale = :de
_(subject).must_equal "Autor J.R.R. ist vom Bloemfontein"
end
end
end
end
end
-1
View File
@@ -5,7 +5,6 @@ require 'shoulda'
require 'mocha/setup' require 'mocha/setup'
require 'fileutils' require 'fileutils'
require 'minitest/reporters' require 'minitest/reporters'
require 'minitest/spec'
require 'twitter_cldr' require 'twitter_cldr'
require 'tmpdir' require 'tmpdir'
-8
View File
@@ -1,8 +0,0 @@
de:
test_class:
author_info:
full: Autor %{author} ist vom %{location}
has_invalid_argument: Willkommen in %{no_matching_method}
hello_world: Hallo Welt
nonexistant_test_class:
never_called: Nie angerufen
-8
View File
@@ -1,8 +0,0 @@
en:
test_class:
author_info:
full: Author %{author} is from %{location}
has_invalid_argument: Welcome to %{no_matching_method}
hello_world: Hello world
nonexistant_test_class:
never_called: Never called
+3 -3
View File
@@ -328,7 +328,7 @@ EOF
test "create with template succeed if template exists" do test "create with template succeed if template exists" do
Precious::App.set(:wiki_options, { :template_page => true }) Precious::App.set(:wiki_options, { :template_page => true })
page='_Template' page='_Template'
post '/gollum/create', :content => 'fake template with some Utf-8: Ü', :page => page, post '/gollum/create', :content => 'fake template', :page => page,
:path => '/', :format => 'markdown', :message => '' :path => '/', :format => 'markdown', :message => ''
follow_redirect! follow_redirect!
assert last_response.ok? assert last_response.ok?
@@ -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
+1 -1
View File
@@ -44,7 +44,7 @@ def load_script(**args)
end end
end end
unless ENV['CI'] unless ENV['TRAVIS']
context '4.x -> 5.x tag migrator' do context '4.x -> 5.x tag migrator' do
include Rack::Test::Methods include Rack::Test::Methods
-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
-43
View File
@@ -1,43 +0,0 @@
# ~*~ encoding: utf-8 ~*~
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
class TestTemplateCascade < Minitest::Unit::TestCase
include Rack::Test::Methods
def setup
@path = cloned_testpath('examples/lotr.git')
Precious::App.set(:gollum_path, @path)
Precious::App.set(:wiki_options, {template_dir: testpath('examples/template_cascade')})
@wiki = Gollum::Wiki.new(@path)
end
def teardown
FileUtils.rm_rf(@path)
end
def app
Precious::App
end
def test_overridden_page_template_is_used
get '/Home'
assert last_response.body.include?('PAGE_OVERRIDE')
end
def test_overridden_navbar_partial_is_used
get '/Home'
assert last_response.body.include?('NAVBAR_OVERRIDE')
end
def test_overridden_templates_are_ignore_without_template_dir_set
Precious::App.set(:wiki_options, {template_dir: nil})
get '/Home'
assert_equal '/Home', last_request.fullpath
assert last_response.ok?
assert_no_match /PAGE_OVERRIDE/, last_response.body
assert_no_match /NAVBAR_OVERRIDE/, last_response.body
end
end