Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f3fd06ef7a | |||
| d97721f38b | |||
| 8d3ec8605e | |||
| 7517389072 | |||
| b7011139cf | |||
| 6e8a68dd0d | |||
| 4e8309d3e4 | |||
| 371ab21d16 | |||
| cbcbc4bc3f | |||
| dc9b2e1766 | |||
| 334df62651 | |||
| 046353cf7e | |||
| 51f2f032d7 | |||
| 70360edb96 | |||
| 2b12ab9206 | |||
| 87a01e04ce | |||
| 5f04200bd0 | |||
| aa823b5a2d | |||
| 9012dee888 | |||
| 81d5f1a8bb | |||
| d2b0a22a8f | |||
| 355e6b1f18 | |||
| 7a2c9107c3 | |||
| 127473fff8 | |||
| 9a79b0a800 | |||
| ca13298d00 | |||
| eaf82e6367 | |||
| cae290ded7 | |||
| a22208a0be | |||
| bc877dc9dc | |||
| 40b1775d42 | |||
| c2dc605adb | |||
| a1e1af07a4 | |||
| 76948130f6 | |||
| f71ba31bfe | |||
| b7caa228e6 | |||
| 0101dd2f65 | |||
| c8baa61fe3 | |||
| 104335706a | |||
| 7c60841bad | |||
| f6a7c57175 | |||
| 730acee609 | |||
| b7295df662 | |||
| aba3ec37d9 | |||
| 020c98bfad | |||
| d33d11e086 | |||
| 2e41751cf6 | |||
| f493150825 | |||
| 68d0dd0cd5 | |||
| 38fc7e69c1 | |||
| 5b7b9f40ae | |||
| 17162aa091 | |||
| 0c89aa2b3e | |||
| 1980e39876 | |||
| 2b949014b8 | |||
| b399496ec2 | |||
| 8433327926 | |||
| bb207f43d0 | |||
| 333af9b76c | |||
| 18a16665cc | |||
| 6c0796733d | |||
| 97ed5a7c57 | |||
| c87c8c446e | |||
| bfbfb21c17 | |||
| 137728cdab | |||
| 3f7fd21d4a | |||
| 2204cef0ef | |||
| 29ad7127d1 | |||
| 123518b940 | |||
| dbe849707a |
@@ -0,0 +1,39 @@
|
|||||||
|
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 }}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
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
|
||||||
@@ -8,3 +8,4 @@ Gemfile.lock
|
|||||||
.*
|
.*
|
||||||
!.sprockets*
|
!.sprockets*
|
||||||
!lib/gollum/public/gollum/stylesheets/_styles.css
|
!lib/gollum/public/gollum/stylesheets/_styles.css
|
||||||
|
!.github*
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
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
|
|
||||||
+4
-2
@@ -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://pgp.mit.edu/pks/lookup?op=vindex&search=0xD637E455CD3E27BF)
|
* [@dometto](https://keys.openpgp.org/vks/v1/by-fingerprint/02354CC9F820B52CC2791979BB8CCC95FD83B795)
|
||||||
|
|
||||||
Lastly, please **consider helping out** by opening a Pull Request!
|
Lastly, please **consider helping out** by opening a Pull Request!
|
||||||
|
|
||||||
@@ -62,6 +62,8 @@ 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
|
||||||
|
|
||||||
@@ -70,7 +72,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 ../lotr.git/
|
git clone ../test/examples/lotr.git/
|
||||||
git log
|
git log
|
||||||
echo "test" > test.md
|
echo "test" > test.md
|
||||||
git add .
|
git add .
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
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"]
|
||||||
@@ -6,5 +6,4 @@ end
|
|||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
gem "rake", '~> 12.3', '>= 12.3.3'
|
gem 'rake', '~> 13.0'
|
||||||
|
|
||||||
+19
@@ -1,3 +1,22 @@
|
|||||||
|
# 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,10 +2,10 @@ gollum -- A git-based Wiki
|
|||||||
====================================
|
====================================
|
||||||
|
|
||||||
[](http://badge.fury.io/rb/gollum)
|
[](http://badge.fury.io/rb/gollum)
|
||||||
[](https://travis-ci.org/gollum/gollum)
|

|
||||||
[](https://www.codetriage.com/gollum/gollum)
|
[](https://www.codetriage.com/gollum/gollum)
|
||||||
|
[](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.
|
||||||
|
|
||||||
@@ -37,16 +37,16 @@ Gollum runs on Unix-like systems using its [adapter](https://github.com/gollum/r
|
|||||||
## INSTALLATION
|
## INSTALLATION
|
||||||
|
|
||||||
1. Ruby is best installed either via [RVM](https://rvm.io/) or a package manager of choice.
|
1. Ruby is best installed either via [RVM](https://rvm.io/) or a package manager of choice.
|
||||||
2. Gollum is best installed via RubyGems:
|
2. Gollum is best installed via RubyGems:
|
||||||
```
|
```
|
||||||
[sudo] gem install gollum
|
[sudo] gem install gollum
|
||||||
```
|
```
|
||||||
|
|
||||||
Installation examples for individual systems can be seen [here](https://github.com/gollum/gollum/wiki/Installation).
|
Installation examples for individual systems can be seen [here](https://github.com/gollum/gollum/wiki/Installation).
|
||||||
|
|
||||||
To run, simply:
|
To run, simply:
|
||||||
|
|
||||||
1. Run: `gollum /path/to/wiki`.
|
1. Run: `gollum /path/to/wiki` where `/path/to/wiki` is an initialized Git repository.
|
||||||
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 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).
|
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).
|
||||||
|
|
||||||
### Rack, with an authentication server
|
### Rack, with an authentication server
|
||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
### Docker
|
### 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).
|
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).
|
||||||
|
|
||||||
### Service
|
### Service
|
||||||
|
|
||||||
Gollum can also be ran as a service. More on that [over here](https://github.com/gollum/gollum/wiki/Gollum-as-a-service).
|
Gollum can also be run 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. |
|
| --template-dir | [PATH] | Specify custom mustache template directory. Only overrides templates that exist in this 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,3 +150,7 @@ 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
|
||||||
|
|
||||||
|
[](https://saucelabs.com)
|
||||||
|
|||||||
+2
-3
@@ -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.') do |path|
|
opts.on('--template-dir [PATH]', 'Specify custom mustache template directory. Only overrides templates that exist in this directory.') do |path|
|
||||||
wiki_options[:template_dir] = path
|
wiki_options[:template_dir] = path
|
||||||
end
|
end
|
||||||
opts.on('--template-page', 'Use _Template in root as a template for new pages.') do
|
opts.on('--template-page', 'Use _Template.{ext} 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,7 +271,6 @@ 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,
|
||||||
|
|||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Initialize the wiki
|
||||||
|
if [ ! -d .git ]; then
|
||||||
|
git init
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start gollum service
|
||||||
|
gollum --mathjax
|
||||||
+20
-17
@@ -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.1.1'
|
s.version = '5.2.3'
|
||||||
s.date = '2020-08-11'
|
s.date = '2021-04-18'
|
||||||
s.license = 'MIT'
|
s.license = 'MIT'
|
||||||
|
|
||||||
s.summary = 'A simple, Git-powered wiki.'
|
s.summary = 'A simple, Git-powered wiki.'
|
||||||
@@ -23,21 +23,23 @@ 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.0'
|
s.add_dependency 'gollum-lib', '~> 5.1'
|
||||||
s.add_dependency 'kramdown', '~> 2.3'
|
s.add_dependency 'kramdown', '~> 2.3'
|
||||||
s.add_dependency 'kramdown-parser-gfm', '~> 1.0.0'
|
s.add_dependency 'kramdown-parser-gfm', '~> 1.1.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', ['>= 0.99.5', '< 1.0.0']
|
s.add_dependency 'mustache-sinatra', '>= 1.0.1', '< 2'
|
||||||
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', '~> 8.5'
|
s.add_dependency 'octicons', '~> 12.0'
|
||||||
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', '~> 3.2'
|
s.add_dependency 'uglifier', '~> 4.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'
|
||||||
@@ -45,7 +47,6 @@ 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,6 +60,7 @@ 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
|
||||||
@@ -68,15 +70,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-459226ba5fc211b78ba9a3aa6ebde96c.json
|
lib/gollum/public/assets/.sprockets-manifest-de7bb79aec424e55af1acdcc4237b301.json
|
||||||
lib/gollum/public/assets/app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js
|
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js
|
||||||
lib/gollum/public/assets/app-6e925e38a12a40c4fa9e0400cc874e0f4f97b66fdeb90a144dea527dbb544fbd.js.gz
|
lib/gollum/public/assets/app-0fd228e26bfbe6fe31a2da268eb0e98e780c1191c1a918adf383377946e9c838.js.gz
|
||||||
lib/gollum/public/assets/app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css
|
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.css
|
||||||
lib/gollum/public/assets/app-b205e593a30f1cc0054e2e9ed9fc8af3658d8ef4a62b9708c20f204560deefb7.css.gz
|
lib/gollum/public/assets/app-ad43ca64b295d8444b10f22ee868f18429268af498f1bc515434878b690e37a2.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-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js
|
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.js
|
||||||
lib/gollum/public/assets/editor-b2c10f22ef6ca1e120956a2d11ff4ca19ac44d7e7240f5cc43ec949184d8b708.js.gz
|
lib/gollum/public/assets/editor-db10c8351306e92f1926ba225d0cd9c8e886482b3b9820a85825ec3abab5f1cf.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
|
||||||
@@ -1174,18 +1176,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.scss
|
lib/gollum/public/gollum/stylesheets/primer.css
|
||||||
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
|
||||||
@@ -1202,6 +1204,7 @@ 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
|
||||||
|
|||||||
+16
-13
@@ -5,32 +5,35 @@ 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.1.1'
|
VERSION = '5.2.3'
|
||||||
|
|
||||||
|
::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 Error < StandardError;
|
class TemplateFilter
|
||||||
end
|
@@filters = {}
|
||||||
|
|
||||||
class DuplicatePageError < Error
|
def self.add_filter(pattern, &replacement)
|
||||||
attr_accessor :dir
|
@@filters[pattern] = replacement
|
||||||
attr_accessor :existing_path
|
end
|
||||||
attr_accessor :attempted_path
|
|
||||||
|
|
||||||
def initialize(dir, existing, attempted, message = nil)
|
def self.apply_filters(data)
|
||||||
@dir = dir
|
@@filters.each do |pattern, replacement|
|
||||||
@existing_path = existing
|
data.gsub!(pattern, replacement.call)
|
||||||
@attempted_path = attempted
|
end
|
||||||
super(message || "Cannot write #{@dir}/#{@attempted_path}, found #{@dir}/#{@existing_path}.")
|
data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+36
-25
@@ -1,4 +1,5 @@
|
|||||||
# ~*~ encoding: utf-8 ~*~
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
require 'sinatra'
|
require 'sinatra'
|
||||||
require 'sinatra/namespace'
|
require 'sinatra/namespace'
|
||||||
@@ -14,12 +15,14 @@ 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__
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ Gollum::set_git_max_filesize(190 * 10**6)
|
|||||||
# See the wiki.rb file for more details on wiki options
|
# See the wiki.rb file for more details on wiki options
|
||||||
|
|
||||||
module Precious
|
module Precious
|
||||||
|
|
||||||
# For use with the --base-path option.
|
# For use with the --base-path option.
|
||||||
class MapGollum
|
class MapGollum
|
||||||
def initialize(base_path)
|
def initialize(base_path)
|
||||||
@@ -63,12 +66,14 @@ module Precious
|
|||||||
@mg.call(env)
|
@mg.call(env)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class App < Sinatra::Base
|
class App < Sinatra::Base
|
||||||
register Mustache::Sinatra
|
register Mustache::Sinatra
|
||||||
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)
|
||||||
@@ -102,11 +107,15 @@ module Precious
|
|||||||
@critic_markup = settings.wiki_options[:critic_markup]
|
@critic_markup = settings.wiki_options[:critic_markup]
|
||||||
@redirects_enabled = settings.wiki_options.fetch(:redirects_enabled, true)
|
@redirects_enabled = settings.wiki_options.fetch(:redirects_enabled, true)
|
||||||
@per_page_uploads = settings.wiki_options[:per_page_uploads]
|
@per_page_uploads = settings.wiki_options[:per_page_uploads]
|
||||||
|
|
||||||
@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
|
||||||
@@ -117,10 +126,10 @@ 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 == :production || settings.environment == :staging)
|
@use_static_assets = settings.wiki_options.fetch(:static, settings.environment != :development)
|
||||||
@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')
|
||||||
|
|
||||||
Sprockets::Helpers.configure do |config|
|
Sprockets::Helpers.configure do |config|
|
||||||
config.environment = settings.sprockets
|
config.environment = settings.sprockets
|
||||||
config.environment.context_class.class_variable_set(:@@base_url, @base_url)
|
config.environment.context_class.class_variable_set(:@@base_url, @base_url)
|
||||||
@@ -219,7 +228,7 @@ module Precious
|
|||||||
|
|
||||||
# AJAX calls only
|
# AJAX calls only
|
||||||
post '/upload_file' do
|
post '/upload_file' do
|
||||||
|
|
||||||
wiki = wiki_new
|
wiki = wiki_new
|
||||||
halt 405 unless wiki.allow_uploads
|
halt 405 unless wiki.allow_uploads
|
||||||
|
|
||||||
@@ -235,7 +244,7 @@ module Precious
|
|||||||
dir.sub!(/^#{wiki.base_path}/, '') if wiki.base_path
|
dir.sub!(/^#{wiki.base_path}/, '') if wiki.base_path
|
||||||
# remove base_url and gollum/* subpath if necessary
|
# remove base_url and gollum/* subpath if necessary
|
||||||
dir.sub!(/^\/gollum\/[-\w]+\//, '')
|
dir.sub!(/^\/gollum\/[-\w]+\//, '')
|
||||||
# remove file extension
|
# remove file extension
|
||||||
dir.sub!(/#{::File.extname(dir)}$/, '')
|
dir.sub!(/#{::File.extname(dir)}$/, '')
|
||||||
# revert escaped whitespaces
|
# revert escaped whitespaces
|
||||||
dir.gsub!(/%20/, ' ')
|
dir.gsub!(/%20/, ' ')
|
||||||
@@ -303,12 +312,13 @@ 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)) if @redirects_enabled
|
wiki.add_redirect(page.url_path, clean_url(new_path), commit) 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?
|
||||||
@@ -316,18 +326,17 @@ module Precious
|
|||||||
end
|
end
|
||||||
|
|
||||||
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, page_name))
|
page = wiki.page(::File.join(path, params[:page]))
|
||||||
|
|
||||||
return if page.nil?
|
return if page.nil?
|
||||||
if etag != page.sha
|
if etag != page.sha
|
||||||
# Signal edit collision and return the page's most recent version
|
# Signal edit collision and return the page's most recent version
|
||||||
halt 412, {etag: page.sha, text_data: page.text_data}.to_json
|
halt 412, {etag: page.sha, text_data: page.text_data}.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
committer = Gollum::Committer.new(wiki, commit_message)
|
committer = Gollum::Committer.new(wiki, commit_message)
|
||||||
commit = { :committer => committer }
|
commit = { :committer => committer }
|
||||||
|
|
||||||
@@ -348,18 +357,15 @@ module Precious
|
|||||||
commit[:message] = "Deleted #{filepath}"
|
commit[:message] = "Deleted #{filepath}"
|
||||||
wiki.delete_file(filepath, commit)
|
wiki.delete_file(filepath, commit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
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.'
|
|
||||||
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,7 +423,7 @@ module Precious
|
|||||||
|
|
||||||
post '/preview' do
|
post '/preview' do
|
||||||
wiki = wiki_new
|
wiki = wiki_new
|
||||||
@name = params[:page] ? strip_page_name(CGI.unescape(params[:page])) : 'Preview'
|
@name = params[:page] ? strip_page_name(params[:page]) : 'Preview'
|
||||||
@page = wiki.preview_page(@name, params[:content], params[:format])
|
@page = wiki.preview_page(@name, 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]
|
||||||
@@ -628,7 +634,7 @@ module Precious
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_file(file)
|
def show_file(file)
|
||||||
return unless file
|
return unless file
|
||||||
if file.on_disk?
|
if file.on_disk?
|
||||||
@@ -639,6 +645,11 @@ 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)
|
||||||
@@ -681,4 +692,4 @@ module Precious
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{"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"}}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"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"}}
|
||||||
-5
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
-21
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
+21
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
+5
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
+24
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
-24
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -7,3 +7,4 @@
|
|||||||
//= 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', paths[ paths.length - 1 ] || '')
|
$form.attr('page', decodeURIComponent(paths[ paths.length - 1 ]) || '')
|
||||||
$form.submit();
|
$form.submit();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -156,12 +156,12 @@ $(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({
|
||||||
title: 'Upload File',
|
title: 'Upload File',
|
||||||
fields: [
|
fields: [
|
||||||
@@ -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,7 @@ $(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', decodeURIComponent(paths[ paths.length - 1 ]) || '')
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: routePath('preview'),
|
url: routePath('preview'),
|
||||||
data: formData,
|
data: formData,
|
||||||
@@ -380,8 +380,12 @@ $(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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// Polyfill to support Internet Explorer
|
||||||
|
if (!Array.prototype.includes) {
|
||||||
|
Array.prototype.includes = function (x) {
|
||||||
|
return 0 <= this.indexOf(x)
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
// 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,7 +147,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#gollum-dialog-dialog-buttons {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ 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,19 +53,85 @@ 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:before {counter-increment: h1; content: counter(h1, var(--header-enum-style)) ". ";}
|
h1 {
|
||||||
h2:before {counter-increment: h2; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) ". ";}
|
counter-increment: h1;
|
||||||
h3:before {counter-increment: h3; content: counter(h1, var(--header-enum-style)) "." counter(h2, var(--header-enum-style)) "." counter(h3, var(--header-enum-style)) ". ";}
|
counter-reset: h2;
|
||||||
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)) ". ";}
|
|
||||||
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)) ". ";}
|
&:before {
|
||||||
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)) ". ";}
|
content: counter(h1, 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 {
|
||||||
@@ -77,43 +143,58 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.anchor {
|
h1,
|
||||||
display: inline-block;
|
h2,
|
||||||
position: absolute;
|
h3,
|
||||||
opacity: 0;
|
h4,
|
||||||
background: url('data:image/svg+xml;utf8,<%= rocticon_css(:link) %>') no-repeat;
|
h5,
|
||||||
background-size: 0.6em 1.35em;
|
h6 {
|
||||||
padding-right: 0.5em;
|
$anchor-icon-size: 20px;
|
||||||
padding-top: 0.4em;
|
|
||||||
margin-left: -0.8em;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
text-decoration: none;
|
|
||||||
transition-property: opacity;
|
|
||||||
transition: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
*:hover > .anchor, .anchor:focus{
|
position: relative;
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.anchor.edit {
|
.anchor {
|
||||||
margin-left: 2em !important;
|
display: inline-block;
|
||||||
margin-top: 0.5em;
|
position: absolute;
|
||||||
height: 0.5em;
|
margin-top: 0.1em;
|
||||||
background: url('data:image/svg+xml;utf8,<%= rocticon_css(:pencil) %>') no-repeat;
|
width: $anchor-icon-size;
|
||||||
|
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 {
|
||||||
@@ -125,13 +206,6 @@ 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 {
|
||||||
@@ -166,18 +240,6 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -615,6 +677,10 @@ a {
|
|||||||
color: #999;
|
color: #999;
|
||||||
background-color: #EAF2F5;
|
background-color: #EAF2F5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gg {
|
||||||
|
color: #000000a0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.type-csharp {
|
.type-csharp {
|
||||||
@@ -639,15 +705,24 @@ a {
|
|||||||
.s, .sc {
|
.s, .sc {
|
||||||
color: #A31515;
|
color: #A31515;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.pagination a.disabled {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
<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="Foo bar">
|
<nav class="tabnav-tabs" aria-label="Toggle edit or preview mode">
|
||||||
<a href="#" id="edit" class="tabnav-tab selected" aria-current="edit">Edit</a>
|
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page">
|
||||||
<a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
|
Edit
|
||||||
</nav>
|
</a>
|
||||||
</div>
|
<a href="#" id="preview" class="tabnav-tab">Preview</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="has-sidebar tabnav-div" id="edit-content">
|
<div class="has-sidebar tabnav-div" id="edit-content">
|
||||||
{{>editor}}
|
{{>editor}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
</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="edit">Edit</a>
|
<a href="#" id="edit" class="tabnav-tab selected" aria-current="page">
|
||||||
<a href="#" id="preview" class="tabnav-tab" aria-current="preview">Preview</a>
|
Edit
|
||||||
|
</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>
|
||||||
|
|||||||
@@ -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}}file-media{{/octicon}}</button>
|
<button class="btn btn-sm function-button" id="function-image" title="Image">{{#octicon}}image{{/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">
|
<select id="keybinding" name="keybinding" class="form-select input-sm">
|
||||||
<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">
|
<select id="wiki_format" name="format" class="form-select input-sm">
|
||||||
{{#formats}}
|
{{#formats}}
|
||||||
{{#enabled}}
|
{{#enabled}}
|
||||||
<option {{#selected}}selected="selected" {{/selected}}value="{{id}}" data-ext="{{ext}}">
|
<option {{#selected}}selected="selected" {{/selected}}value="{{id}}" data-ext="{{ext}}">
|
||||||
|
|||||||
@@ -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-7">{{message}}<br/>
|
<span class="flex-auto col-5">{{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}}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
{{#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}}';
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<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>
|
||||||
@@ -1,43 +1,103 @@
|
|||||||
<nav class="actions pt-4">
|
<nav class="TableObject actions pt-4 px-2 px-lg-0 overflow-x-scroll">
|
||||||
|
<div class="TableObject-item hide-lg hide-xl">
|
||||||
<div class="TableObject">
|
{{>mobilenav}}
|
||||||
<div class="TableObject-item">
|
</div>
|
||||||
<a class="btn" id="minibutton-home" href="{{page_route}}">Home</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="TableObject-item hide-sm hide-md">
|
||||||
|
<a class="btn btn-sm" id="minibutton-home" href="{{page_route}}">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="TableObject-item TableObject-item--primary px-2" {{^search}}style="visibility:hidden"{{/search}}>
|
<div
|
||||||
{{>searchbar}}
|
class="TableObject-item TableObject-item--primary px-2"
|
||||||
</div>
|
{{^search}}style="visibility:hidden"{{/search}}
|
||||||
|
>
|
||||||
<div class="TableObject-item">
|
{{>searchbar}}
|
||||||
{{#overview}}<a class="btn" id="minibutton-overview" href="{{overview_path}}">Overview</a>{{/overview}}
|
</div>
|
||||||
{{#latest_changes}}<a class="btn" id="minibutton-latest-changes" href="{{latest_changes_path}}">Latest Changes</a>{{/latest_changes}}
|
|
||||||
</div>
|
<div class="TableObject-item hide-sm hide-md">
|
||||||
|
<div class="BtnGroup d-flex">
|
||||||
{{#history}}
|
{{#overview}}
|
||||||
<div class="TableObject-item pl-1">
|
<a
|
||||||
<a class="btn" id="minibutton-history" href="{{history_path}}/{{escaped_url_path}}">Page History</a>
|
class="btn BtnGroup-item btn-sm"
|
||||||
</div>
|
href="{{overview_path}}"
|
||||||
{{/history}}
|
id="minibutton-overview"
|
||||||
|
>
|
||||||
{{#allow_editing}}
|
Overview
|
||||||
<div class="TableObject-item pl-1">
|
</a>
|
||||||
{{#allow_uploads}}
|
{{/overview}}
|
||||||
<a class="btn" id="minibutton-upload-page" href="#">Upload</a>
|
|
||||||
{{/allow_uploads}}
|
{{#latest_changes}}
|
||||||
{{#editable}}
|
<a
|
||||||
<a class="btn" id="minibutton-rename-page" href="#">Rename</a>
|
class="btn BtnGroup-item btn-sm"
|
||||||
<a class="btn" id="minibutton-edit-page" href="{{edit_path}}/{{escaped_url_path}}">Edit</a>
|
href="{{latest_changes_path}}"
|
||||||
<a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
|
id="minibutton-latest-changes"
|
||||||
{{/editable}}
|
>
|
||||||
{{^editable}}
|
Latest Changes
|
||||||
{{#newable}}
|
</a>
|
||||||
<a class="btn btn-primary" id="minibutton-new-page" href="#">New</a>
|
{{/latest_changes}}
|
||||||
{{/newable}}
|
</div>
|
||||||
{{/editable}}
|
</div>
|
||||||
</div>
|
|
||||||
{{/allow_editing}}
|
<div class="TableObject-item px-2">
|
||||||
|
<div class="BtnGroup d-flex">
|
||||||
</div>
|
{{#history}}
|
||||||
</nav>
|
<a
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md"
|
||||||
|
href="{{history_path}}/{{escaped_url_path}}"
|
||||||
|
id="minibutton-history"
|
||||||
|
>
|
||||||
|
History
|
||||||
|
</a>
|
||||||
|
{{/history}}
|
||||||
|
|
||||||
|
{{#allow_editing}}
|
||||||
|
{{#allow_uploads}}
|
||||||
|
<button
|
||||||
|
class="btn BtnGroup-item btn-sm hide-sm hide-md
|
||||||
|
minibutton-upload-page"
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</button>
|
||||||
|
{{/allow_uploads}}
|
||||||
|
|
||||||
|
{{#editable}}
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -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="{{url}}" data-confirm="Are you sure you want to delete {{name}}?">{{#octicon}}trashcan{{/octicon}}</button>{{/is_file}}
|
{{#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}}
|
||||||
{{/allow_editing}}
|
{{/allow_editing}}
|
||||||
</li>
|
</li>
|
||||||
{{/files_folders}}
|
{{/files_folders}}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<div id="wiki-content">
|
<div id="wiki-content" class="px-2 px-lg-0">
|
||||||
<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}}
|
||||||
@@ -9,14 +8,7 @@
|
|||||||
{{{toc_content}}}
|
{{{toc_content}}}
|
||||||
</div>
|
</div>
|
||||||
{{/has_toc}}
|
{{/has_toc}}
|
||||||
{{#has_sidebar}}
|
<div id="wiki-body" class="gollum-{{format}}-content">
|
||||||
<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">
|
||||||
@@ -24,14 +16,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/has_header}}
|
{{/has_header}}
|
||||||
<div class="markdown-body {{#header_enum?}}header-enum{{/header_enum?}}" {{#header_enum?}}style="--header-enum-style:{{header_enum_style}};"{{/header_enum?}}>
|
<div class="main-content clearfix container-lg">
|
||||||
{{{rendered_metadata}}}
|
<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?}}>
|
||||||
{{{content}}}
|
{{{rendered_metadata}}}
|
||||||
|
{{{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">
|
<div id="wiki-footer" class="gollum-{{footer_format}}-content my-2">
|
||||||
<div id="footer-content" class="Box Box-condensed markdown-body pl-2">
|
<div id="footer-content" class="Box Box-condensed markdown-body px-4">
|
||||||
{{{footer_content}}}
|
{{{footer_content}}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,5 +58,5 @@
|
|||||||
{{/historical}}
|
{{/historical}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,12 +23,19 @@ module Precious
|
|||||||
end
|
end
|
||||||
|
|
||||||
def files
|
def files
|
||||||
files = @diff.split(%r{^diff --git a/.+ b/.+$}).reject(&:empty?)
|
files = @diff.force_encoding(Encoding::UTF_8).scan(%r{
|
||||||
|
^diff\ --git\ # diff start
|
||||||
|
.+? # diff body
|
||||||
|
(?=^diff\ --git|\Z) # scan until next diff or string
|
||||||
|
}sxmu)
|
||||||
|
|
||||||
files.map do |diff|
|
files.map do |diff|
|
||||||
matched = diff.match(%r{(?<=^--- a/).+$})
|
match = diff.match(%r{^diff --git (")?[ab]/(.+)(?(1)") (")?[ab]/(.+)(?(3)")})
|
||||||
matched = diff.match(%r{(?<=^\+\+\+ b/).+$}) if matched.nil?
|
path = match[2]
|
||||||
|
path = match[4] if path.nil?
|
||||||
|
|
||||||
{
|
{
|
||||||
path: matched[0],
|
path: path,
|
||||||
lines: lines(diff)
|
lines: lines(diff)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,16 +19,21 @@ module Precious
|
|||||||
|
|
||||||
def lines(diff = @diff)
|
def lines(diff = @diff)
|
||||||
lines = []
|
lines = []
|
||||||
lines_to_parse = diff.split("\n")[4..-1]
|
lines_to_parse = diff.split("\n")[3..-1]
|
||||||
# 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.
|
lines_to_parse = lines_to_parse[2..-1] if lines_to_parse[0] =~ /^(---|rename to )/
|
||||||
# Make sure to skip that header line if it is present.
|
|
||||||
lines_to_parse = lines_to_parse[1..-1] if lines_to_parse[0].start_with?('+++')
|
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?('+++')
|
||||||
|
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 if diff
|
end
|
||||||
lines
|
lines
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -41,6 +46,8 @@ 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 =~ /^\-/
|
||||||
@@ -53,7 +60,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 line =~ /^@@/
|
if git_line?(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
|
||||||
@@ -75,7 +82,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 line =~ /^@@/
|
if git_line?(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
|
||||||
@@ -93,6 +100,10 @@ module Precious
|
|||||||
end
|
end
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def git_line?(line)
|
||||||
|
!!(line =~ /^(\\ No newline|Binary files|@@)/)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -61,7 +61,10 @@ module Precious
|
|||||||
url.compact!
|
url.compact!
|
||||||
return nil if url.empty?
|
return nil if url.empty?
|
||||||
|
|
||||||
::File.join(*url).gsub(%r{/{2,}}, '/')
|
_url = ::File.join(*url)
|
||||||
|
_url.gsub!(%r{/{2,}}, '/')
|
||||||
|
_url.gsub!(%r{\?}, '%3F')
|
||||||
|
_url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
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
|
||||||
@@ -6,10 +6,11 @@ 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
|
||||||
|
|
||||||
alias_method :h, :escape_html
|
alias_method :h, :escape_html
|
||||||
|
|
||||||
attr_reader :name, :path
|
attr_reader :name, :path
|
||||||
@@ -47,7 +48,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,6 +4,7 @@ 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}"
|
||||||
@@ -25,9 +26,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">#{title}</li>}
|
breadcrumb << %{<li class="breadcrumb-item" aria-current="page">#{CGI.escapeHTML(title.to_s)}</li>}
|
||||||
else
|
else
|
||||||
breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{title}</a></li>}
|
breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{CGI.escapeHTML(title.to_s)}</a></li>}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
breadcrumb << %{</ol></nav>}
|
breadcrumb << %{</ol></nav>}
|
||||||
@@ -51,9 +52,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 result_path != '.gitkeep'
|
elsif !HIDDEN_PATHS.include?(result_path)
|
||||||
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, is_file: true}
|
files_and_folders << {name: result.filename, icon: rocticon('file'), type: 'file', url: file_url, file_path: result.escaped_url_path, 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
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ module Precious
|
|||||||
def page_header
|
def page_header
|
||||||
title
|
title
|
||||||
end
|
end
|
||||||
|
|
||||||
def breadcrumb
|
def breadcrumb
|
||||||
path = Pathname.new(@page.url_path).parent
|
path = Pathname.new(@page.url_path).parent
|
||||||
return '' if path.to_s == '.'
|
return '' if path.to_s == '.'
|
||||||
@@ -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}/">#{element}</a></li>}
|
breadcrumb << %{<li class="breadcrumb-item"><a href="#{overview_path}/#{crumb}/">#{CGI.escapeHTML(element.to_s)}</a></li>}
|
||||||
end
|
end
|
||||||
breadcrumb << %{</ol></nav>}
|
breadcrumb << %{</ol></nav>}
|
||||||
breadcrumb.join("\n")
|
breadcrumb.join("\n")
|
||||||
@@ -123,7 +123,11 @@ module Precious
|
|||||||
def bar_side
|
def bar_side
|
||||||
@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
|
||||||
@@ -264,7 +268,6 @@ module Precious
|
|||||||
end
|
end
|
||||||
result << "</tr>\n</table>\n"
|
result << "</tr>\n</table>\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
@@ -10,3 +10,4 @@ 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,3 +10,4 @@ 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
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
f803c64d11407b23797325e3843f3f378b78f611
|
181c757cca395d4da18701d069a6b8123e88e040
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<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>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<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>
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
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
|
||||||
+2
-1
@@ -5,6 +5,7 @@ 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'
|
||||||
|
|
||||||
@@ -93,4 +94,4 @@ def context(*args, &block)
|
|||||||
klass.class_eval &block
|
klass.class_eval &block
|
||||||
end
|
end
|
||||||
|
|
||||||
$contexts = []
|
$contexts = []
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
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
@@ -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', :page => page,
|
post '/gollum/create', :content => 'fake template with some Utf-8: Ü', :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%20Gamgee.mediawiki'
|
post "/gollum/preview", :content => 'abc', :format => 'markdown', :page => 'Samewise Gamgee.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')
|
assert last_response.body.include?('<script defer src="/wiki/gollum/assets/mathjax/MathJax.js?config=')
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'compare view' do
|
test 'compare view' do
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# ~*~ 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
|
||||||
@@ -35,9 +35,11 @@ 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
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def load_script(**args)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless ENV['TRAVIS']
|
unless ENV['CI']
|
||||||
|
|
||||||
context '4.x -> 5.x tag migrator' do
|
context '4.x -> 5.x tag migrator' do
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|||||||
@@ -44,6 +44,23 @@ 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, "><script>alert("malicious-content");</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
|
||||||
@@ -72,6 +89,17 @@ 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")
|
||||||
@@ -79,5 +107,7 @@ 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
|
||||||
|
|||||||
+115
-17
@@ -13,6 +13,67 @@ 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, "><script>alert("malicious-content");</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)
|
||||||
@@ -24,10 +85,46 @@ 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)
|
||||||
actual = @view.title
|
assert @view.page_header, "1 & 2"
|
||||||
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")
|
||||||
@@ -93,21 +190,6 @@ 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')
|
||||||
@@ -127,4 +209,20 @@ 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
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# ~*~ 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
|
||||||
Reference in New Issue
Block a user