Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fda5bcf3f6 | |||
| 01005fdccf | |||
| 95d35d38da | |||
| 81c90e55a7 | |||
| 3f0b61081b | |||
| ecc317886a | |||
| 4b2dc8e5c0 | |||
| 6f870501a0 | |||
| f30058f4ee | |||
| 82ce013cab | |||
| 0c36cdf5ba | |||
| 6159fcd4a2 | |||
| 8f7793f461 | |||
| 589b4bce39 |
@@ -1,12 +1,22 @@
|
||||
name: Deploy docker
|
||||
on: [push]
|
||||
env:
|
||||
DEPLOY_NAME: gollumwiki/gollum:latest
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
release:
|
||||
types: [published]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.ref == 'refs/heads/master' }}
|
||||
steps:
|
||||
- name: Set deploy name to master
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
echo "DEPLOY_NAME=gollumwiki/gollum:master" >> $GITHUB_ENV
|
||||
- name: Set deploy name to release version
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
echo "DEPLOY_NAME=gollumwiki/gollum:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
- name: Check Out Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Login
|
||||
|
||||
@@ -6,7 +6,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ruby: [jruby-9.2.18]
|
||||
ruby: [jruby-9.3.2.0]
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v2
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ruby: [2.6, 2.7, 3.0]
|
||||
ruby: ['2.6', '2.7', '3.0', '3.1']
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
@@ -17,9 +17,6 @@ gem 'warbler', platforms: :jruby
|
||||
# Note that Nokogiri 1.11+ does not support Ruby v2.4.x anymore. So to make our
|
||||
# current CI workflows pass, we should only try to install this version of
|
||||
# Nokogiri for newer Ruby versions.
|
||||
#
|
||||
# [1]: https://github.com/gollum/gollum/issues/1779
|
||||
gem 'nokogiri', '1.12.4' unless RUBY_VERSION.include? '2.4'
|
||||
|
||||
gemspec
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ Gollum comes with the following command line options:
|
||||
| --css | none | Tell Gollum to inject custom CSS into each page. Uses `custom.css` from wiki root.<sup>3</sup> |
|
||||
| --js | none | Tell Gollum to inject custom JS into each page. Uses `custom.js` from wiki root.<sup>3</sup> |
|
||||
| --no-edit | none | Disable the feature of editing pages. |
|
||||
| --local-time | none | Use the browser's local timezone instead of the server's for displaying dates. Default: false.
|
||||
| --follow-renames, --no-follow-renames | none | Follow pages across renames in the History view. Default: true.
|
||||
| --allow-uploads | [MODE] | Enable file uploads. If set to `dir`, Gollum will store all uploads in the `/uploads/` directory in repository root. If set to `page`, Gollum will store each upload at the currently edited page.<sup>4</sup> |
|
||||
| --mathjax | none | Enables MathJax (renders mathematical equations). By default, uses the `TeX-AMS-MML_HTMLorMML` config with the `autoload-all` extension.<sup>5</sup> |
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
require 'rubygems'
|
||||
require 'rake'
|
||||
require 'date'
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
@@ -38,14 +37,6 @@ def bump_version
|
||||
new_version
|
||||
end
|
||||
|
||||
def date
|
||||
Date.today.to_s
|
||||
end
|
||||
|
||||
def rubyforge_project
|
||||
name
|
||||
end
|
||||
|
||||
def gemspec_file
|
||||
"#{name}.gemspec"
|
||||
end
|
||||
@@ -143,12 +134,9 @@ task :gemspec => :validate do
|
||||
spec = File.read(gemspec_file)
|
||||
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
||||
|
||||
# replace name version and date
|
||||
# replace name and version
|
||||
replace_header(head, :name)
|
||||
replace_header(head, :version)
|
||||
replace_header(head, :date)
|
||||
#comment this out if your rubyforge_project has a different name
|
||||
replace_header(head, :rubyforge_project)
|
||||
|
||||
# determine file list from git ls-files
|
||||
files = `git ls-files`.
|
||||
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env ruby
|
||||
#!/usr/bin/env -S ruby -Eutf-8
|
||||
|
||||
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
||||
|
||||
@@ -112,6 +112,9 @@ MSG
|
||||
opts.on('--no-edit', 'Disable the feature of editing pages.') do
|
||||
wiki_options[:allow_editing] = false
|
||||
end
|
||||
opts.on('--local-time', "Use the browser's local timezone instead of the server's for displaying dates.") do
|
||||
wiki_options[:show_local_time] = true
|
||||
end
|
||||
opts.on('--follow-renames', 'Follow pages across renames in the History view. Default: true.') do
|
||||
wiki_options[:follow_renames] = true
|
||||
end
|
||||
|
||||
+20
-8
@@ -11,8 +11,11 @@ migrate_options = {
|
||||
:hyphenate => true
|
||||
}
|
||||
|
||||
def setting(const)
|
||||
Object.const_defined?(const.upcase) && Object.const_get(const.upcase)
|
||||
def setting(variable_name)
|
||||
class_variable_name = :"@@#{variable_name.to_s}"
|
||||
|
||||
Object.class_variable_defined?(class_variable_name) &&
|
||||
Object.class_variable_get(class_variable_name)
|
||||
end
|
||||
|
||||
opts = OptionParser.new do |opts|
|
||||
@@ -78,8 +81,11 @@ end
|
||||
begin
|
||||
opts.parse!
|
||||
migrate_options.each do |setting, value|
|
||||
const = setting.to_s.upcase
|
||||
Object.const_set(const, value) unless Object.const_defined?(const)
|
||||
variable_name = :"@@#{setting.to_s}"
|
||||
|
||||
unless Object.class_variable_defined?(variable_name)
|
||||
Object.class_variable_set(variable_name, value)
|
||||
end
|
||||
end
|
||||
wiki_options[:page_file_dir] = setting(:page_file_dir) ? setting(:page_file_dir) : wiki_options[:page_file_dir] # Allow settings :page_file_dir through PAGE_FILE_DIR constant.
|
||||
rescue OptionParser::InvalidOption
|
||||
@@ -88,7 +94,7 @@ rescue OptionParser::InvalidOption
|
||||
exit
|
||||
end
|
||||
|
||||
REPO = ARGV[0] || Dir.pwd
|
||||
wiki_directory = ARGV[0] || Dir.pwd
|
||||
|
||||
require 'gollum-lib'
|
||||
|
||||
@@ -232,8 +238,12 @@ end
|
||||
|
||||
filter_chain = [:PlainTextMigrator, :CodeMigrator, :TagMigrator]
|
||||
|
||||
wiki = ::Gollum::Wiki.new(REPO, wiki_options.merge({:filter_chain => filter_chain}))
|
||||
TREE = wiki.tree_list(wiki.ref, true, true).map {|file| ::File.join('/', file.path)}
|
||||
wiki = ::Gollum::Wiki.new(wiki_directory, wiki_options.merge({:filter_chain => filter_chain}))
|
||||
|
||||
Object.class_variable_set(
|
||||
:"@@wiki_tree",
|
||||
wiki.tree_list(wiki.ref, true, true).map {|file| ::File.join('/', file.path)}
|
||||
)
|
||||
|
||||
def find_linked(link)
|
||||
link.gsub!(' ', '-') if setting(:hyphenate) # Match paths containing dashes instead of spaces
|
||||
@@ -243,7 +253,9 @@ def find_linked(link)
|
||||
test_path = ::File.extname(link).empty? ? /#{link}\..+/ : link
|
||||
# Select pages from the wiki whose path =~ 'Foo/Bar/Samwi.*'
|
||||
# Match case-insenstively to mimic 4.x behavior!
|
||||
TREE.select {|path| path =~ /^\/(.*\/)?#{test_path}/i}
|
||||
Object.class_variable_get(:"@@wiki_tree").select { |path|
|
||||
path =~ /^\/(.*\/)?#{test_path}/i
|
||||
}
|
||||
end
|
||||
|
||||
def log(kind, msg = nil)
|
||||
|
||||
@@ -5,6 +5,14 @@ if [ ! -d .git ]; then
|
||||
git init
|
||||
fi
|
||||
|
||||
# Set git user.name and user.email
|
||||
if [ ${GOLLUM_AUTHOR_USERNAME:+1} ]; then
|
||||
git config user.name "${GOLLUM_AUTHOR_USERNAME}"
|
||||
fi
|
||||
if [ ${GOLLUM_AUTHOR_EMAIL:+1} ]; then
|
||||
git config user.email "${GOLLUM_AUTHOR_EMAIL}"
|
||||
fi
|
||||
|
||||
# Start gollum service
|
||||
[[ "$@" != *--mathjax* ]] && echo "WARNING: Mathjax will soon be disabled by default. To explicitly enable it, use --mathjax" >&2
|
||||
exec gollum $@ --mathjax
|
||||
|
||||
+2
-4
@@ -1,12 +1,9 @@
|
||||
Gem::Specification.new do |s|
|
||||
s.specification_version = 2 if s.respond_to? :specification_version=
|
||||
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
||||
s.rubygems_version = '1.3.5'
|
||||
s.required_ruby_version = '>= 1.9'
|
||||
s.required_ruby_version = '>= 2.6'
|
||||
|
||||
s.name = 'gollum'
|
||||
s.version = '5.2.3'
|
||||
s.date = '2021-04-18'
|
||||
s.license = 'MIT'
|
||||
|
||||
s.summary = 'A simple, Git-powered wiki.'
|
||||
@@ -1152,6 +1149,7 @@ Gem::Specification.new do |s|
|
||||
lib/gollum/public/gollum/javascript/ace/worker-xquery.js
|
||||
lib/gollum/public/gollum/javascript/app.js
|
||||
lib/gollum/public/gollum/javascript/clipboard.min.js
|
||||
lib/gollum/public/gollum/javascript/date.min.js
|
||||
lib/gollum/public/gollum/javascript/editor.js
|
||||
lib/gollum/public/gollum/javascript/editor/gollum.editor.js
|
||||
lib/gollum/public/gollum/javascript/editor/langs/asciidoc.js
|
||||
|
||||
+3
-2
@@ -29,9 +29,10 @@ module Gollum
|
||||
@@filters[pattern] = replacement
|
||||
end
|
||||
|
||||
def self.apply_filters(data)
|
||||
def self.apply_filters(wiki_page, data)
|
||||
@@filters.each do |pattern, replacement|
|
||||
data.gsub!(pattern, replacement.call)
|
||||
params = replacement.parameters.length == 0 ? nil : wiki_page
|
||||
data.gsub!(pattern, replacement.call(*params))
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
+41
-26
@@ -103,16 +103,14 @@ module Precious
|
||||
end
|
||||
|
||||
before do
|
||||
settings.wiki_options[:allow_editing] = settings.wiki_options.fetch(:allow_editing, true)
|
||||
@allow_editing = settings.wiki_options[:allow_editing]
|
||||
@allow_editing = settings.wiki_options.fetch(:allow_editing, true)
|
||||
@critic_markup = settings.wiki_options[:critic_markup]
|
||||
@redirects_enabled = settings.wiki_options.fetch(:redirects_enabled, true)
|
||||
@per_page_uploads = settings.wiki_options[:per_page_uploads]
|
||||
@show_local_time = settings.wiki_options.fetch(:show_local_time, false)
|
||||
|
||||
@wiki_title = settings.wiki_options.fetch(:title, 'Gollum Wiki')
|
||||
|
||||
forbid unless @allow_editing || request.request_method == 'GET'
|
||||
|
||||
if settings.wiki_options[:template_dir]
|
||||
Precious::Views::Layout.extend Precious::Views::TemplateCascade
|
||||
Precious::Views::Layout.template_priority_path = settings.wiki_options[:template_dir]
|
||||
@@ -142,6 +140,8 @@ module Precious
|
||||
config.manifest = Sprockets::Manifest.new(settings.sprockets, @static_assets_path)
|
||||
end
|
||||
end
|
||||
|
||||
forbid unless @allow_editing || request.request_method == 'GET'
|
||||
end
|
||||
|
||||
get '/' do
|
||||
@@ -178,7 +178,9 @@ module Precious
|
||||
content_type :json
|
||||
if page = wiki_page(params[:path]).page
|
||||
version = page.last_version
|
||||
{:author => version.author.name, :date => version.authored_date}.to_json
|
||||
authored_date = version.authored_date
|
||||
authored_date = authored_date.utc.iso8601 if @show_local_time
|
||||
{:author => version.author.name, :date => authored_date}.to_json
|
||||
end
|
||||
end
|
||||
|
||||
@@ -366,7 +368,7 @@ module Precious
|
||||
@name = wikip.name
|
||||
@ext = wikip.ext
|
||||
@path = wikip.path
|
||||
@template_page = load_template(@path) if settings.wiki_options[:template_page]
|
||||
@template_page = load_template(wikip, @path) if settings.wiki_options[:template_page]
|
||||
@allow_uploads = wikip.wiki.allow_uploads
|
||||
@upload_dest = find_upload_dest(wikip.fullpath)
|
||||
|
||||
@@ -440,23 +442,18 @@ module Precious
|
||||
mustache :page
|
||||
end
|
||||
|
||||
get %r{
|
||||
/history/ # match any URL beginning with /history/
|
||||
(.+?) # extract the full path (including any directories)
|
||||
/
|
||||
([0-9a-f]{40}) # match SHA
|
||||
}x do |path, version|
|
||||
wiki = wiki_new
|
||||
show_history wiki_page(path, wiki.commit_for(version), wiki)
|
||||
end
|
||||
|
||||
get '/history/*' do
|
||||
wikip = wiki_page(params[:splat].first)
|
||||
@name = wikip.fullname
|
||||
@page = wikip.page
|
||||
@page_num = [params[:page_num].to_i, 1].max
|
||||
@max_count = settings.wiki_options.fetch(:pagination_count, 10)
|
||||
unless @page.nil?
|
||||
@wiki = @page.wiki
|
||||
@versions = @page.versions(
|
||||
per_page: @max_count,
|
||||
page_num: @page_num,
|
||||
follow: settings.wiki_options.fetch(:follow_renames, true)
|
||||
)
|
||||
mustache :history
|
||||
else
|
||||
redirect to("/")
|
||||
end
|
||||
show_history wiki_page(params[:splat].first)
|
||||
end
|
||||
|
||||
get '/latest_changes' do
|
||||
@@ -603,6 +600,24 @@ module Precious
|
||||
|
||||
private
|
||||
|
||||
def show_history(wikip)
|
||||
@name = wikip.fullname
|
||||
@page = wikip.page
|
||||
@page_num = [params[:page_num].to_i, 1].max
|
||||
@max_count = settings.wiki_options.fetch(:pagination_count, 10)
|
||||
unless @page.nil?
|
||||
@wiki = @page.wiki
|
||||
@versions = @page.versions(
|
||||
per_page: @max_count,
|
||||
page_num: @page_num,
|
||||
follow: settings.wiki_options.fetch(:follow_renames, true)
|
||||
)
|
||||
mustache :history
|
||||
else
|
||||
redirect to("/")
|
||||
end
|
||||
end
|
||||
|
||||
def show_page_or_file(fullpath)
|
||||
wiki = wiki_new
|
||||
if page = wiki.page(fullpath)
|
||||
@@ -645,9 +660,9 @@ module Precious
|
||||
end
|
||||
end
|
||||
|
||||
def load_template(path)
|
||||
def load_template(wiki_page, 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
|
||||
template_page ? Gollum::TemplateFilter.apply_filters(wiki_page, template_page.text_data) : nil
|
||||
end
|
||||
|
||||
def update_wiki_page(wiki, page, content, commit, name = nil, format = nil)
|
||||
@@ -659,9 +674,9 @@ module Precious
|
||||
wiki.update_page(page, name, format, content.to_s, commit)
|
||||
end
|
||||
|
||||
def wiki_page(path, version = nil)
|
||||
def wiki_page(path, version = nil, wiki = nil)
|
||||
pathname = (Pathname.new('/') + path).cleanpath
|
||||
wiki = wiki_new
|
||||
wiki = wiki_new if wiki.nil?
|
||||
OpenStruct.new(:wiki => wiki, :page => wiki.page(pathname.to_s, version = version),
|
||||
:name => pathname.basename.sub_ext('').to_s, :path => pathname.dirname.to_s, :ext => pathname.extname, :fullname => pathname.basename.to_s, :fullpath => pathname.to_s)
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//= require jquery-1.7.2.min
|
||||
//= require identicon
|
||||
//= require date.min
|
||||
//= require mousetrap.min
|
||||
//= require clipboard.min
|
||||
//= require gollum
|
||||
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @overview datejs
|
||||
* @version 1.0.0-rc3
|
||||
* @author Gregory Wild-Smith <gregory@wild-smith.com>
|
||||
* @copyright 2015 Gregory Wild-Smith
|
||||
* @license MIT
|
||||
* @homepage https://github.com/abritinthebay/datejs
|
||||
*/
|
||||
/*
|
||||
2015 Gregory Wild-Smith
|
||||
@license MIT
|
||||
@homepage https://github.com/abritinthebay/datejs
|
||||
*/
|
||||
(function(){var h=Date,f=Date.CultureStrings?Date.CultureStrings.lang:null,d={},c={getFromKey:function(a,b){var e;e=Date.CultureStrings&&Date.CultureStrings[b]&&Date.CultureStrings[b][a]?Date.CultureStrings[b][a]:c.buildFromDefault(a);"/"===a.charAt(0)&&(e=c.buildFromRegex(a,b));return e},getFromObjectValues:function(a,b){var e,g={};for(e in a)a.hasOwnProperty(e)&&(g[e]=c.getFromKey(a[e],b));return g},getFromObjectKeys:function(a,b){var e,g={};for(e in a)a.hasOwnProperty(e)&&(g[c.getFromKey(e,b)]=
|
||||
a[e]);return g},getFromArray:function(a,b){for(var e=[],g=0;g<a.length;g++)g in a&&(e[g]=c.getFromKey(a[g],b));return e},buildFromDefault:function(a){var b,e,g;switch(a){case "name":b="en-US";break;case "englishName":b="English (United States)";break;case "nativeName":b="English (United States)";break;case "twoDigitYearMax":b=2049;break;case "firstDayOfWeek":b=0;break;default:if(b=a,g=a.split("_"),e=g.length,1<e&&"/"!==a.charAt(0)&&(a=g[e-1].toLowerCase(),"initial"===a||"abbr"===a))b=g[0]}return b},
|
||||
buildFromRegex:function(a,b){return Date.CultureStrings&&Date.CultureStrings[b]&&Date.CultureStrings[b][a]?new RegExp(Date.CultureStrings[b][a],"i"):new RegExp(a.replace(RegExp("/","g"),""),"i")}},a=function(a,b){var e=b?b:f;d[a]=a;return"object"===typeof a?a instanceof Array?c.getFromArray(a,e):c.getFromObjectKeys(a,e):c.getFromKey(a,e)},b=function(a){a=Date.Config.i18n+a+".js";var b=document.getElementsByTagName("head")[0]||document.documentElement,e=document.createElement("script");e.src=a;var g=
|
||||
{done:function(){}};e.onload=e.onreadystatechange=function(){this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState||(g.done(),b.removeChild(e))};setTimeout(function(){b.insertBefore(e,b.firstChild)},0);return{done:function(a){g.done=function(){a&&setTimeout(a,0)}}}},e={buildFromMethodHash:function(a){for(var b in a)a.hasOwnProperty(b)&&(a[b]=e[a[b]]());return a},timeZoneDST:function(){return a({CHADT:"+1345",NZDT:"+1300",AEDT:"+1100",ACDT:"+1030",AZST:"+0500",IRDT:"+0430",EEST:"+0300",
|
||||
CEST:"+0200",BST:"+0100",PMDT:"-0200",ADT:"-0300",NDT:"-0230",EDT:"-0400",CDT:"-0500",MDT:"-0600",PDT:"-0700",AKDT:"-0800",HADT:"-0900"})},timeZoneStandard:function(){return a({LINT:"+1400",TOT:"+1300",CHAST:"+1245",NZST:"+1200",NFT:"+1130",SBT:"+1100",AEST:"+1000",ACST:"+0930",JST:"+0900",CWST:"+0845",CT:"+0800",ICT:"+0700",MMT:"+0630",BST:"+0600",NPT:"+0545",IST:"+0530",PKT:"+0500",AFT:"+0430",MSK:"+0400",IRST:"+0330",FET:"+0300",EET:"+0200",CET:"+0100",GMT:"+0000",UTC:"+0000",CVT:"-0100",GST:"-0200",
|
||||
BRT:"-0300",NST:"-0330",AST:"-0400",EST:"-0500",CST:"-0600",MST:"-0700",PST:"-0800",AKST:"-0900",MIT:"-0930",HST:"-1000",SST:"-1100",BIT:"-1200"})},timeZones:function(a){var b;a.timezones=[];for(b in a.abbreviatedTimeZoneStandard)a.abbreviatedTimeZoneStandard.hasOwnProperty(b)&&a.timezones.push({name:b,offset:a.abbreviatedTimeZoneStandard[b]});for(b in a.abbreviatedTimeZoneDST)a.abbreviatedTimeZoneDST.hasOwnProperty(b)&&a.timezones.push({name:b,offset:a.abbreviatedTimeZoneDST[b],dst:!0});return a.timezones},
|
||||
days:function(){return a("Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "))},dayAbbr:function(){return a("Sun Mon Tue Wed Thu Fri Sat".split(" "))},dayShortNames:function(){return a("Su Mo Tu We Th Fr Sa".split(" "))},dayFirstLetters:function(){return a("S_Sun_Initial M_Mon_Initial T_Tues_Initial W_Wed_Initial T_Thu_Initial F_Fri_Initial S_Sat_Initial".split(" "))},months:function(){return a("January February March April May June July August September October November December".split(" "))},
|
||||
monthAbbr:function(){return a("Jan_Abbr Feb_Abbr Mar_Abbr Apr_Abbr May_Abbr Jun_Abbr Jul_Abbr Aug_Abbr Sep_Abbr Oct_Abbr Nov_Abbr Dec_Abbr".split(" "))},formatPatterns:function(){return c.getFromObjectValues({shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},
|
||||
Date.i18n.currentLanguage())},regex:function(){return c.getFromObjectValues({inTheMorning:"/( in the )(morn(ing)?)\\b/",thisMorning:"/(this )(morn(ing)?)\\b/",amThisMorning:"/(\b\\d(am)? )(this )(morn(ing)?)/",inTheEvening:"/( in the )(even(ing)?)\\b/",thisEvening:"/(this )(even(ing)?)\\b/",pmThisEvening:"/(\b\\d(pm)? )(this )(even(ing)?)/",jan:"/jan(uary)?/",feb:"/feb(ruary)?/",mar:"/mar(ch)?/",apr:"/apr(il)?/",may:"/may/",jun:"/jun(e)?/",jul:"/jul(y)?/",aug:"/aug(ust)?/",sep:"/sep(t(ember)?)?/",
|
||||
oct:"/oct(ober)?/",nov:"/nov(ember)?/",dec:"/dec(ember)?/",sun:"/^su(n(day)?)?/",mon:"/^mo(n(day)?)?/",tue:"/^tu(e(s(day)?)?)?/",wed:"/^we(d(nesday)?)?/",thu:"/^th(u(r(s(day)?)?)?)?/",fri:"/fr(i(day)?)?/",sat:"/^sa(t(urday)?)?/",future:"/^next/",past:"/^last|past|prev(ious)?/",add:"/^(\\+|aft(er)?|from|hence)/",subtract:"/^(\\-|bef(ore)?|ago)/",yesterday:"/^yes(terday)?/",today:"/^t(od(ay)?)?/",tomorrow:"/^tom(orrow)?/",now:"/^n(ow)?/",millisecond:"/^ms|milli(second)?s?/",second:"/^sec(ond)?s?/",
|
||||
minute:"/^mn|min(ute)?s?/",hour:"/^h(our)?s?/",week:"/^w(eek)?s?/",month:"/^m(onth)?s?/",day:"/^d(ay)?s?/",year:"/^y(ear)?s?/",shortMeridian:"/^(a|p)/",longMeridian:"/^(a\\.?m?\\.?|p\\.?m?\\.?)/",timezone:"/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\\s*(\\+|\\-)\\s*\\d\\d\\d\\d?)|gmt|utc)/",ordinalSuffix:"/^\\s*(st|nd|rd|th)/",timeContext:"/^\\s*(\\:|a(?!u|p)|p)/"},Date.i18n.currentLanguage())}},g=function(){var a=c.getFromObjectValues({name:"name",englishName:"englishName",nativeName:"nativeName",
|
||||
amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:"firstDayOfWeek",twoDigitYearMax:"twoDigitYearMax",dateElementOrder:"mdy"},Date.i18n.currentLanguage()),b=e.buildFromMethodHash({dayNames:"days",abbreviatedDayNames:"dayAbbr",shortestDayNames:"dayShortNames",firstLetterDayNames:"dayFirstLetters",monthNames:"months",abbreviatedMonthNames:"monthAbbr",formatPatterns:"formatPatterns",regexPatterns:"regex",abbreviatedTimeZoneDST:"timeZoneDST",abbreviatedTimeZoneStandard:"timeZoneStandard"}),g;for(g in b)b.hasOwnProperty(g)&&
|
||||
(a[g]=b[g]);e.timeZones(a);return a};h.i18n={__:function(m,b){return a(m,b)},currentLanguage:function(){return f||"en-US"},setLanguage:function(a,e,c){var d=!1;if(e||"en-US"===a||Date.CultureStrings&&Date.CultureStrings[a])f=a,Date.CultureStrings=Date.CultureStrings||{},Date.CultureStrings.lang=a,Date.CultureInfo=new g;else if(!Date.CultureStrings||!Date.CultureStrings[a])if("undefined"!==typeof exports&&this.exports!==exports)try{require("../i18n/"+a+".js"),f=a,Date.CultureStrings.lang=a,Date.CultureInfo=
|
||||
new g}catch(p){throw Error("The DateJS IETF language tag '"+a+"' could not be loaded by Node. It likely does not exist.");}else if(Date.Config&&Date.Config.i18n)d=!0,b(a).done(function(){f=a;Date.CultureStrings=Date.CultureStrings||{};Date.CultureStrings.lang=a;Date.CultureInfo=new g;h.Parsing.Normalizer.buildReplaceData();h.Grammar&&h.Grammar.buildGrammarFormats();c&&setTimeout(c,0)});else return Date.console.error("The DateJS IETF language tag '"+a+"' is not available and has not been loaded."),
|
||||
!1;h.Parsing.Normalizer.buildReplaceData();h.Grammar&&h.Grammar.buildGrammarFormats();!d&&c&&setTimeout(c,0)},getLoggedKeys:function(){return d},updateCultureInfo:function(){Date.CultureInfo=new g}};h.i18n.updateCultureInfo()})();
|
||||
(function(){var h=Date,f=h.prototype,d=function(a,b){b||(b=2);return("000"+a).slice(-1*b)};h.console="undefined"!==typeof window&&"undefined"!==typeof window.console&&"undefined"!==typeof window.console.log?console:{log:function(){},error:function(){}};h.Config=h.Config||{};h.initOverloads=function(){h.now?h._now||(h._now=h.now):h._now=function(){return(new Date).getTime()};h.now=function(a){return a?h.present():h._now()};f.toISOString||(f.toISOString=function(){return this.getUTCFullYear()+"-"+d(this.getUTCMonth()+
|
||||
1)+"-"+d(this.getUTCDate())+"T"+d(this.getUTCHours())+":"+d(this.getUTCMinutes())+":"+d(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1E3).toFixed(3)).slice(2,5)+"Z"});void 0===f._toString&&(f._toString=f.toString)};h.initOverloads();h.today=function(){return(new Date).clearTime()};h.present=function(){return new Date};h.compare=function(a,b){if(isNaN(a)||isNaN(b))throw Error(a+" - "+b);if(a instanceof Date&&b instanceof Date)return a<b?-1:a>b?1:0;throw new TypeError(a+" - "+b);};h.equals=
|
||||
function(a,b){return 0===a.compareTo(b)};h.getDayName=function(a){return Date.CultureInfo.dayNames[a]};h.getDayNumberFromName=function(a){var b=Date.CultureInfo.dayNames,e=Date.CultureInfo.abbreviatedDayNames,g=Date.CultureInfo.shortestDayNames;a=a.toLowerCase();for(var m=0;m<b.length;m++)if(b[m].toLowerCase()===a||e[m].toLowerCase()===a||g[m].toLowerCase()===a)return m;return-1};h.getMonthNumberFromName=function(a){var b=Date.CultureInfo.monthNames,e=Date.CultureInfo.abbreviatedMonthNames;a=a.toLowerCase();
|
||||
for(var g=0;g<b.length;g++)if(b[g].toLowerCase()===a||e[g].toLowerCase()===a)return g;return-1};h.getMonthName=function(a){return Date.CultureInfo.monthNames[a]};h.isLeapYear=function(a){return 0===a%4&&0!==a%100||0===a%400};h.getDaysInMonth=function(a,b){!b&&h.validateMonth(a)&&(b=a,a=Date.today().getFullYear());return[31,h.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]};f.getDaysInMonth=function(){return h.getDaysInMonth(this.getFullYear(),this.getMonth())};h.getTimezoneAbbreviation=function(a,
|
||||
b){var e,g=b?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard;for(e in g)if(g.hasOwnProperty(e)&&g[e]===a)return e;return null};h.getTimezoneOffset=function(a,b){var e,g=[],m=Date.CultureInfo.timezones;a||(a=(new Date).getTimezone());for(e=0;e<m.length;e++)m[e].name===a.toUpperCase()&&g.push(e);if(!m[g[0]])return null;if(1!==g.length&&b)for(e=0;e<g.length;e++){if(m[g[e]].dst)return m[g[e]].offset}else return m[g[0]].offset};h.getQuarter=function(a){a=a||new Date;
|
||||
return[1,2,3,4][Math.floor(a.getMonth()/3)]};h.getDaysLeftInQuarter=function(a){a=a||new Date;var b=new Date(a);b.setMonth(b.getMonth()+3-b.getMonth()%3,0);return Math.floor((b-a)/864E5)};var c=function(a,b,e,g){if("undefined"===typeof a)return!1;if("number"!==typeof a)throw new TypeError(a+" is not a Number.");return a<b||a>e?!1:!0};h.validateMillisecond=function(a){return c(a,0,999,"millisecond")};h.validateSecond=function(a){return c(a,0,59,"second")};h.validateMinute=function(a){return c(a,0,
|
||||
59,"minute")};h.validateHour=function(a){return c(a,0,23,"hour")};h.validateDay=function(a,b,e){return void 0===b||null===b||void 0===e||null===e?!1:c(a,1,h.getDaysInMonth(b,e),"day")};h.validateWeek=function(a){return c(a,0,53,"week")};h.validateMonth=function(a){return c(a,0,11,"month")};h.validateYear=function(a){return c(a,-271822,275760,"year")};h.validateTimezone=function(a){return 1==={ACDT:1,ACST:1,ACT:1,ADT:1,AEDT:1,AEST:1,AFT:1,AKDT:1,AKST:1,AMST:1,AMT:1,ART:1,AST:1,AWDT:1,AWST:1,AZOST:1,
|
||||
AZT:1,BDT:1,BIOT:1,BIT:1,BOT:1,BRT:1,BST:1,BTT:1,CAT:1,CCT:1,CDT:1,CEDT:1,CEST:1,CET:1,CHADT:1,CHAST:1,CHOT:1,ChST:1,CHUT:1,CIST:1,CIT:1,CKT:1,CLST:1,CLT:1,COST:1,COT:1,CST:1,CT:1,CVT:1,CWST:1,CXT:1,DAVT:1,DDUT:1,DFT:1,EASST:1,EAST:1,EAT:1,ECT:1,EDT:1,EEDT:1,EEST:1,EET:1,EGST:1,EGT:1,EIT:1,EST:1,FET:1,FJT:1,FKST:1,FKT:1,FNT:1,GALT:1,GAMT:1,GET:1,GFT:1,GILT:1,GIT:1,GMT:1,GST:1,GYT:1,HADT:1,HAEC:1,HAST:1,HKT:1,HMT:1,HOVT:1,HST:1,ICT:1,IDT:1,IOT:1,IRDT:1,IRKT:1,IRST:1,IST:1,JST:1,KGT:1,KOST:1,KRAT:1,
|
||||
KST:1,LHST:1,LINT:1,MAGT:1,MART:1,MAWT:1,MDT:1,MET:1,MEST:1,MHT:1,MIST:1,MIT:1,MMT:1,MSK:1,MST:1,MUT:1,MVT:1,MYT:1,NCT:1,NDT:1,NFT:1,NPT:1,NST:1,NT:1,NUT:1,NZDT:1,NZST:1,OMST:1,ORAT:1,PDT:1,PET:1,PETT:1,PGT:1,PHOT:1,PHT:1,PKT:1,PMDT:1,PMST:1,PONT:1,PST:1,PYST:1,PYT:1,RET:1,ROTT:1,SAKT:1,SAMT:1,SAST:1,SBT:1,SCT:1,SGT:1,SLST:1,SRT:1,SST:1,SYOT:1,TAHT:1,THA:1,TFT:1,TJT:1,TKT:1,TLT:1,TMT:1,TOT:1,TVT:1,UCT:1,ULAT:1,UTC:1,UYST:1,UYT:1,UZT:1,VET:1,VLAT:1,VOLT:1,VOST:1,VUT:1,WAKT:1,WAST:1,WAT:1,WEDT:1,WEST:1,
|
||||
WET:1,WST:1,YAKT:1,YEKT:1,Z:1}[a]};h.validateTimezoneOffset=function(a){return-841<a&&721>a}})();
|
||||
(function(){var h=Date,f=h.prototype,d=function(a,b){b||(b=2);return("000"+a).slice(-1*b)},c=function(a){var b={},e=this,g,c;c=function(b,g,c){if("day"===b){b=void 0!==a.month?a.month:e.getMonth();var d=void 0!==a.year?a.year:e.getFullYear();return h[g](c,d,b)}return h[g](c)};for(g in a)if(Object.prototype.hasOwnProperty.call(a,g)){var d="validate"+g.charAt(0).toUpperCase()+g.slice(1);h[d]&&null!==a[g]&&c(g,d,a[g])&&(b[g]=a[g])}return b};f.clearTime=function(){this.setHours(0);this.setMinutes(0);
|
||||
this.setSeconds(0);this.setMilliseconds(0);return this};f.setTimeToNow=function(){var a=new Date;this.setHours(a.getHours());this.setMinutes(a.getMinutes());this.setSeconds(a.getSeconds());this.setMilliseconds(a.getMilliseconds());return this};f.clone=function(){return new Date(this.getTime())};f.compareTo=function(a){return Date.compare(this,a)};f.equals=function(a){return Date.equals(this,void 0!==a?a:new Date)};f.between=function(a,b){return this.getTime()>=a.getTime()&&this.getTime()<=b.getTime()};
|
||||
f.isAfter=function(a){return 1===this.compareTo(a||new Date)};f.isBefore=function(a){return-1===this.compareTo(a||new Date)};f.isToday=f.isSameDay=function(a){return this.clone().clearTime().equals((a||new Date).clone().clearTime())};f.addMilliseconds=function(a){if(!a)return this;this.setTime(this.getTime()+1*a);return this};f.addSeconds=function(a){return a?this.addMilliseconds(1E3*a):this};f.addMinutes=function(a){return a?this.addMilliseconds(6E4*a):this};f.addHours=function(a){return a?this.addMilliseconds(36E5*
|
||||
a):this};f.addDays=function(a){if(!a)return this;this.setDate(this.getDate()+1*a);return this};f.addWeekdays=function(a){if(!a)return this;var b=this.getDay(),e=Math.ceil(Math.abs(a)/7);(0===b||6===b)&&0<a&&(this.next().monday(),this.addDays(-1),b=this.getDay());if(0>a){for(;0>a;)this.addDays(-1),b=this.getDay(),0!==b&&6!==b&&a++;return this}if(5<a||6-b<=a)a+=2*e;return this.addDays(a)};f.addWeeks=function(a){return a?this.addDays(7*a):this};f.addMonths=function(a){if(!a)return this;var b=this.getDate();
|
||||
this.setDate(1);this.setMonth(this.getMonth()+1*a);this.setDate(Math.min(b,h.getDaysInMonth(this.getFullYear(),this.getMonth())));return this};f.addQuarters=function(a){return a?this.addMonths(3*a):this};f.addYears=function(a){return a?this.addMonths(12*a):this};f.add=function(a){if("number"===typeof a)return this._orient=a,this;a.day&&0!==a.day-this.getDate()&&this.setDate(a.day);a.milliseconds&&this.addMilliseconds(a.milliseconds);a.seconds&&this.addSeconds(a.seconds);a.minutes&&this.addMinutes(a.minutes);
|
||||
a.hours&&this.addHours(a.hours);a.weeks&&this.addWeeks(a.weeks);a.months&&this.addMonths(a.months);a.years&&this.addYears(a.years);a.days&&this.addDays(a.days);return this};f.getWeek=function(a){var b=new Date(this.valueOf());a?(b.addMinutes(b.getTimezoneOffset()),a=b.clone()):a=this;a=(a.getDay()+6)%7;b.setDate(b.getDate()-a+3);a=b.valueOf();b.setMonth(0,1);4!==b.getDay()&&b.setMonth(0,1+(4-b.getDay()+7)%7);return 1+Math.ceil((a-b)/6048E5)};f.getISOWeek=function(){return d(this.getWeek(!0))};f.setWeek=
|
||||
function(a){return 0===a-this.getWeek()?1!==this.getDay()?this.moveToDayOfWeek(1,1<this.getDay()?-1:1):this:this.moveToDayOfWeek(1,1<this.getDay()?-1:1).addWeeks(a-this.getWeek())};f.setQuarter=function(a){a=Math.abs(3*(a-1)+1);return this.setMonth(a,1)};f.getQuarter=function(){return Date.getQuarter(this)};f.getDaysLeftInQuarter=function(){return Date.getDaysLeftInQuarter(this)};f.moveToNthOccurrence=function(a,b){if("Weekday"===a){if(0<b)this.moveToFirstDayOfMonth(),this.is().weekday()&&--b;else if(0>
|
||||
b)this.moveToLastDayOfMonth(),this.is().weekday()&&(b+=1);else return this;return this.addWeekdays(b)}var e=0;if(0<b)e=b-1;else if(-1===b)return this.moveToLastDayOfMonth(),this.getDay()!==a&&this.moveToDayOfWeek(a,-1),this;return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(a,1).addWeeks(e)};var a=function(a,b,e){return function(g,c){var d=(g-this[a]()+e*(c||1))%e;return this[b](0===d?d+e*(c||1):d)}};f.moveToDayOfWeek=a("getDay","addDays",7);f.moveToMonth=a("getMonth","addMonths",12);
|
||||
f.getOrdinate=function(){var a=this.getDate();return b(a)};f.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/864E5)+1};f.getTimezone=function(){return h.getTimezoneAbbreviation(this.getUTCOffset(),this.isDaylightSavingTime())};f.setTimezoneOffset=function(a){var b=this.getTimezoneOffset();return(a=-6*Number(a)/10)||0===a?this.addMinutes(a-b):this};f.setTimezone=function(a){return this.setTimezoneOffset(h.getTimezoneOffset(a))};f.hasDaylightSavingTime=
|
||||
function(){return Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset()};f.isDaylightSavingTime=function(){return Date.today().set({month:0,day:1}).getTimezoneOffset()!==this.getTimezoneOffset()};f.getUTCOffset=function(a){a=-10*(a||this.getTimezoneOffset())/6;if(0>a)return a=(a-1E4).toString(),a.charAt(0)+a.substr(2);a=(a+1E4).toString();return"+"+a.substr(1)};f.getElapsed=function(a){return(a||new Date)-this};f.set=function(a){a=c.call(this,
|
||||
a);for(var b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var e=b.charAt(0).toUpperCase()+b.slice(1),g,d;"week"!==b&&"month"!==b&&"timezone"!==b&&"timezoneOffset"!==b&&(e+="s");g="add"+e;d="get"+e;"month"===b?g+="s":"year"===b&&(d="getFullYear");if("day"!==b&&"timezone"!==b&&"timezoneOffset"!==b&&"week"!==b&&"hour"!==b)this[g](a[b]-this[d]());else if("timezone"===b||"timezoneOffset"===b||"week"===b||"hour"===b)this["set"+e](a[b])}a.day&&this.addDays(a.day-this.getDate());return this};f.moveToFirstDayOfMonth=
|
||||
function(){return this.set({day:1})};f.moveToLastDayOfMonth=function(){return this.set({day:h.getDaysInMonth(this.getFullYear(),this.getMonth())})};var b=function(a){switch(1*a){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th"}},e=function(a){var b=Date.CultureInfo.formatPatterns;switch(a){case "d":return this.toString(b.shortDate);case "D":return this.toString(b.longDate);case "F":return this.toString(b.fullDateTime);case "m":return this.toString(b.monthDay);
|
||||
case "r":case "R":return a=this.clone().addMinutes(this.getTimezoneOffset()),a.toString(b.rfc1123)+" GMT";case "s":return this.toString(b.sortableDateTime);case "t":return this.toString(b.shortTime);case "T":return this.toString(b.longTime);case "u":return a=this.clone().addMinutes(this.getTimezoneOffset()),a.toString(b.universalSortableDateTime);case "y":return this.toString(b.yearMonth);default:return!1}},g=function(a){return function(e){if("\\"===e.charAt(0))return e.replace("\\","");switch(e){case "hh":return d(13>
|
||||
a.getHours()?0===a.getHours()?12:a.getHours():a.getHours()-12);case "h":return 13>a.getHours()?0===a.getHours()?12:a.getHours():a.getHours()-12;case "HH":return d(a.getHours());case "H":return a.getHours();case "mm":return d(a.getMinutes());case "m":return a.getMinutes();case "ss":return d(a.getSeconds());case "s":return a.getSeconds();case "yyyy":return d(a.getFullYear(),4);case "yy":return d(a.getFullYear());case "y":return a.getFullYear();case "E":case "dddd":return Date.CultureInfo.dayNames[a.getDay()];
|
||||
case "ddd":return Date.CultureInfo.abbreviatedDayNames[a.getDay()];case "dd":return d(a.getDate());case "d":return a.getDate();case "MMMM":return Date.CultureInfo.monthNames[a.getMonth()];case "MMM":return Date.CultureInfo.abbreviatedMonthNames[a.getMonth()];case "MM":return d(a.getMonth()+1);case "M":return a.getMonth()+1;case "t":return 12>a.getHours()?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case "tt":return 12>a.getHours()?Date.CultureInfo.amDesignator:
|
||||
Date.CultureInfo.pmDesignator;case "S":return b(a.getDate());case "W":return a.getWeek();case "WW":return a.getISOWeek();case "Q":return"Q"+a.getQuarter();case "q":return String(a.getQuarter());case "z":return a.getTimezone();case "Z":case "X":return Date.getTimezoneOffset(a.getTimezone());case "ZZ":return-60*a.getTimezoneOffset();case "u":return a.getDay();case "L":return h.isLeapYear(a.getFullYear())?1:0;case "B":return"@"+(a.getUTCSeconds()+60*a.getUTCMinutes()+3600*(a.getUTCHours()+1))/86.4;default:return e}}};
|
||||
f.toString=function(a,b){if(!b&&a&&1===a.length&&(output=e.call(this,a)))return output;var c=g(this);return a?a.replace(/((\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S|q|Q|WW?W?W?)(?![^\[]*\]))/g,c).replace(/\[|\]/g,""):this._toString()}})();
|
||||
(function(){var h=Date,f=h.prototype,d=Number.prototype;f._orient=1;f._nth=null;f._is=!1;f._same=!1;f._isSecond=!1;d._dateElement="days";f.next=function(){this._move=!0;this._orient=1;return this};h.next=function(){return h.today().next()};f.last=f.prev=f.previous=function(){this._move=!0;this._orient=-1;return this};h.last=h.prev=h.previous=function(){return h.today().last()};f.is=function(){this._is=!0;return this};f.same=function(){this._same=!0;this._isSecond=!1;return this};f.today=function(){return this.same().day()};
|
||||
f.weekday=function(){return this._nth?m("Weekday").call(this):this._move?this.addWeekdays(this._orient):this._is?(this._is=!1,!this.is().sat()&&!this.is().sun()):!1};f.weekend=function(){return this._is?(this._is=!1,this.is().sat()||this.is().sun()):!1};f.at=function(a){return"string"===typeof a?h.parse(this.toString("d")+" "+a):this.set(a)};d.fromNow=d.after=function(a){var b={};b[this._dateElement]=this;return(a?a.clone():new Date).add(b)};d.ago=d.before=function(a){var b={};b["s"!==this._dateElement[this._dateElement.length-
|
||||
1]?this._dateElement+"s":this._dateElement]=-1*this;return(a?a.clone():new Date).add(b)};var c="sunday monday tuesday wednesday thursday friday saturday".split(/\s/),a="january february march april may june july august september october november december".split(/\s/),b="Millisecond Second Minute Hour Day Week Month Year Quarter Weekday".split(/\s/),e="Milliseconds Seconds Minutes Hours Date Week Month FullYear Quarter".split(/\s/),g="final first second third fourth fifth".split(/\s/);f.toObject=function(){for(var a=
|
||||
{},g=0;g<b.length;g++)this["get"+e[g]]&&(a[b[g].toLowerCase()]=this["get"+e[g]]());return a};h.fromObject=function(a){a.week=null;return Date.today().set(a)};var m=function(a){return function(){if(this._is)return this._is=!1,this.getDay()===a;this._move&&(this._move=null);if(null!==this._nth){this._isSecond&&this.addSeconds(-1*this._orient);this._isSecond=!1;var b=this._nth;this._nth=null;var e=this.clone().moveToLastDayOfMonth();this.moveToNthOccurrence(a,b);if(this>e)throw new RangeError(h.getDayName(a)+
|
||||
" does not occur "+b+" times in the month of "+h.getMonthName(e.getMonth())+" "+e.getFullYear()+".");return this}return this.moveToDayOfWeek(a,this._orient)}},k=function(a,b,e){for(var g=0;g<a.length;g++)h[a[g].toUpperCase()]=h[a[g].toUpperCase().substring(0,3)]=g,h[a[g]]=h[a[g].substring(0,3)]=b(g),f[a[g]]=f[a[g].substring(0,3)]=e(g)};k(c,function(a){return function(){var b=h.today(),e=a-b.getDay();0===a&&1===Date.CultureInfo.firstDayOfWeek&&0!==b.getDay()&&(e+=7);return b.addDays(e)}},m);k(a,function(a){return function(){return h.today().set({month:a,
|
||||
day:1})}},function(a){return function(){return this._is?(this._is=!1,this.getMonth()===a):this.moveToMonth(a,this._orient)}});for(var a=function(a){return function(e){if(this._isSecond)return this._isSecond=!1,this;if(this._same){this._same=this._is=!1;var g=this.toObject();e=(e||new Date).toObject();for(var c="",d=a.toLowerCase(),d="s"===d[d.length-1]?d.substring(0,d.length-1):d,f=b.length-1;-1<f;f--){c=b[f].toLowerCase();if(g[c]!==e[c])return!1;if(d===c)break}return!0}"s"!==a.substring(a.length-
|
||||
1)&&(a+="s");this._move&&(this._move=null);return this["add"+a](this._orient)}},k=function(a){return function(){this._dateElement=a;return this}},n=0;n<b.length;n++)c=b[n].toLowerCase(),"weekday"!==c&&(f[c]=f[c+"s"]=a(b[n]),d[c]=d[c+"s"]=k(c+"s"));f._ss=a("Second");d=function(a){return function(b){if(this._same)return this._ss(b);if(b||0===b)return this.moveToNthOccurrence(b,a);this._nth=a;return 2!==a||void 0!==b&&null!==b?this:(this._isSecond=!0,this.addSeconds(this._orient))}};for(c=0;c<g.length;c++)f[g[c]]=
|
||||
0===c?d(-1):d(c)})();
|
||||
(function(){Date.Parsing={Exception:function(a){this.message="Parse error at '"+a.substring(0,10)+" ...'"}};var h=Date.Parsing,f=[0,31,59,90,120,151,181,212,243,273,304,334],d=[0,31,60,91,121,152,182,213,244,274,305,335];h.isLeapYear=function(a){return 0===a%4&&0!==a%100||0===a%400};var c={multiReplace:function(a,b){for(var e in b)if(Object.prototype.hasOwnProperty.call(b,e)){var g;"function"!==typeof b[e]&&(g=b[e]instanceof RegExp?b[e]:new RegExp(b[e],"g"));a=a.replace(g,e)}return a},getDayOfYearFromWeek:function(a){var b;
|
||||
a.weekDay=a.weekDay||0===a.weekDay?a.weekDay:1;b=new Date(a.year,0,4);b=(0===b.getDay()?7:b.getDay())+3;a.dayOfYear=7*a.week+(0===a.weekDay?7:a.weekDay)-b;return a},getDayOfYear:function(a,b){a.dayOfYear||(a=c.getDayOfYearFromWeek(a));for(var e=0;e<=b.length;e++)if(a.dayOfYear<b[e]||e===b.length){a.day=a.day?a.day:a.dayOfYear-b[e-1];break}else a.month=e;return a},adjustForTimeZone:function(a,b){var e;"Z"===a.zone.toUpperCase()||0===a.zone_hours&&0===a.zone_minutes?e=-b.getTimezoneOffset():(e=60*a.zone_hours+
|
||||
(a.zone_minutes||0),"+"===a.zone_sign&&(e*=-1),e-=b.getTimezoneOffset());b.setMinutes(b.getMinutes()+e);return b},setDefaults:function(a){a.year=a.year||Date.today().getFullYear();a.hours=a.hours||0;a.minutes=a.minutes||0;a.seconds=a.seconds||0;a.milliseconds=a.milliseconds||0;if(a.month||!a.week&&!a.dayOfYear)a.month=a.month||0,a.day=a.day||1;return a},dataNum:function(a,b,e,g){var c=1*a;return b?g?a?1*b(a):a:a?b(c):a:e?a&&"undefined"!==typeof a?c:a:a?c:a},timeDataProcess:function(a){var b={},e;
|
||||
for(e in a.data)a.data.hasOwnProperty(e)&&(b[e]=a.ignore[e]?a.data[e]:c.dataNum(a.data[e],a.mods[e],a.explict[e],a.postProcess[e]));a.data.secmins&&(a.data.secmins=60*a.data.secmins.replace(",","."),b.minutes?b.seconds||(b.seconds=a.data.secmins):b.minutes=a.data.secmins,delete a.secmins);return b},buildTimeObjectFromData:function(a){return c.timeDataProcess({data:{year:a[1],month:a[5],day:a[7],week:a[8],dayOfYear:a[10],hours:a[15],zone_hours:a[23],zone_minutes:a[24],zone:a[21],zone_sign:a[22],weekDay:a[9],
|
||||
minutes:a[16],seconds:a[19],milliseconds:a[20],secmins:a[18]},mods:{month:function(a){return a-1},weekDay:function(a){a=Math.abs(a);return 7===a?0:a},minutes:function(a){return a.replace(":","")},seconds:function(a){return Math.floor(1*a.replace(":","").replace(",","."))},milliseconds:function(a){return 1E3*a.replace(",",".")}},postProcess:{minutes:!0,seconds:!0,milliseconds:!0},explict:{zone_hours:!0,zone_minutes:!0},ignore:{zone:!0,zone_sign:!0,secmins:!0}})},addToHash:function(a,b,e){for(var g=
|
||||
b.length,c=0;c<g;c++)a[b[c]]=e[c];return a},combineRegex:function(a,b){return new RegExp("(("+a.source+")\\s("+b.source+"))")},getDateNthString:function(a,b,e){if(a)return Date.today().addDays(e).toString("d");if(b)return Date.today().last()[e]().toString("d")},buildRegexData:function(a){for(var b=[],e=a.length,g=0;g<e;g++)"[object Array]"===Object.prototype.toString.call(a[g])?b.push(this.combineRegex(a[g][0],a[g][1])):b.push(a[g]);return b}};h.processTimeObject=function(a){var b;c.setDefaults(a);
|
||||
b=h.isLeapYear(a.year)?d:f;a.month||!a.week&&!a.dayOfYear?a.dayOfYear=b[a.month]+a.day:c.getDayOfYear(a,b);b=new Date(a.year,a.month,a.day,a.hours,a.minutes,a.seconds,a.milliseconds);a.zone&&c.adjustForTimeZone(a,b);return b};h.ISO={regex:/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-4])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?\s?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/,
|
||||
parse:function(a){a=a.match(this.regex);if(!a||!a.length)return null;a=c.buildTimeObjectFromData(a);return a.year&&(a.year||a.month||a.day||a.week||a.dayOfYear)?h.processTimeObject(a):null}};h.Numeric={isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},regex:/\b([0-1]?[0-9])([0-3]?[0-9])([0-2]?[0-9]?[0-9][0-9])\b/i,parse:function(a){var b,e={},g=Date.CultureInfo.dateElementOrder.split("");if(!this.isNumeric(a)||"+"===a[0]&&"-"===a[0])return null;if(5>a.length&&0>a.indexOf(".")&&0>a.indexOf("/"))return e.year=
|
||||
a,h.processTimeObject(e);a=a.match(this.regex);if(!a||!a.length)return null;for(b=0;b<g.length;b++)switch(g[b]){case "d":e.day=a[b+1];break;case "m":e.month=a[b+1]-1;break;case "y":e.year=a[b+1]}return h.processTimeObject(e)}};h.Normalizer={regexData:function(){var a=Date.CultureInfo.regexPatterns;return c.buildRegexData([a.tomorrow,a.yesterday,[a.past,a.mon],[a.past,a.tue],[a.past,a.wed],[a.past,a.thu],[a.past,a.fri],[a.past,a.sat],[a.past,a.sun]])},basicReplaceHash:function(){var a=Date.CultureInfo.regexPatterns;
|
||||
return{January:a.jan.source,February:a.feb,March:a.mar,April:a.apr,May:a.may,June:a.jun,July:a.jul,August:a.aug,September:a.sep,October:a.oct,November:a.nov,December:a.dec,"":/\bat\b/gi," ":/\s{2,}/,am:a.inTheMorning,"9am":a.thisMorning,pm:a.inTheEvening,"7pm":a.thisEvening}},keys:function(){return[c.getDateNthString(!0,!1,1),c.getDateNthString(!0,!1,-1),c.getDateNthString(!1,!0,"monday"),c.getDateNthString(!1,!0,"tuesday"),c.getDateNthString(!1,!0,"wednesday"),c.getDateNthString(!1,!0,"thursday"),
|
||||
c.getDateNthString(!1,!0,"friday"),c.getDateNthString(!1,!0,"saturday"),c.getDateNthString(!1,!0,"sunday")]},buildRegexFunctions:function(){var a=Date.CultureInfo.regexPatterns,b=Date.i18n.__,b=new RegExp("(\\b\\d\\d?("+b("AM")+"|"+b("PM")+")? )("+a.tomorrow.source.slice(1)+")","i");this.replaceFuncs=[[new RegExp(a.today.source+"(?!\\s*([+-]))\\b"),function(a){return 1<a.length?Date.today().toString("d"):a}],[b,function(a,b){return Date.today().addDays(1).toString("d")+" "+b}],[a.amThisMorning,function(a,
|
||||
b){return b}],[a.pmThisEvening,function(a,b){return b}]]},buildReplaceData:function(){this.buildRegexFunctions();this.replaceHash=c.addToHash(this.basicReplaceHash(),this.keys(),this.regexData())},stringReplaceFuncs:function(a){for(var b=0;b<this.replaceFuncs.length;b++)a=a.replace(this.replaceFuncs[b][0],this.replaceFuncs[b][1]);return a},parse:function(a){a=this.stringReplaceFuncs(a);a=c.multiReplace(a,this.replaceHash);try{var b=a.split(/([\s\-\.\,\/\x27]+)/);3===b.length&&h.Numeric.isNumeric(b[0])&&
|
||||
h.Numeric.isNumeric(b[2])&&4<=b[2].length&&"d"===Date.CultureInfo.dateElementOrder[0]&&(a="1/"+b[0]+"/"+b[2])}catch(e){}return a}};h.Normalizer.buildReplaceData()})();
|
||||
(function(){for(var h=Date.Parsing,f=h.Operators={rtoken:function(a){return function(e){var g=e.match(a);if(g)return[g[0],e.substring(g[0].length)];throw new h.Exception(e);}},token:function(){return function(a){return f.rtoken(new RegExp("^\\s*"+a+"\\s*"))(a)}},stoken:function(a){return f.rtoken(new RegExp("^"+a))},until:function(a){return function(e){for(var g=[],c=null;e.length;){try{c=a.call(this,e)}catch(d){g.push(c[0]);e=c[1];continue}break}return[g,e]}},many:function(a){return function(e){for(var g=
|
||||
[],c=null;e.length;){try{c=a.call(this,e)}catch(d){break}g.push(c[0]);e=c[1]}return[g,e]}},optional:function(a){return function(e){var g=null;try{g=a.call(this,e)}catch(c){return[null,e]}return[g[0],g[1]]}},not:function(a){return function(e){try{a.call(this,e)}catch(g){return[null,e]}throw new h.Exception(e);}},ignore:function(a){return a?function(e){var g=null,g=a.call(this,e);return[null,g[1]]}:null},product:function(){for(var a=arguments[0],e=Array.prototype.slice.call(arguments,1),g=[],c=0;c<
|
||||
a.length;c++)g.push(f.each(a[c],e));return g},cache:function(a){var e={},g=0,c=[],d=Date.Config.CACHE_MAX||1E5,f=null;return function(l){if(g===d)for(var p=0;10>p;p++){var q=c.shift();q&&(delete e[q],g--)}try{f=e[l]=e[l]||a.call(this,l)}catch(s){f=e[l]=s}g++;c.push(l);if(f instanceof h.Exception)throw f;return f}},any:function(){var a=arguments;return function(e){for(var g=null,c=0;c<a.length;c++)if(null!=a[c]){try{g=a[c].call(this,e)}catch(d){g=null}if(g)return g}throw new h.Exception(e);}},each:function(){var a=
|
||||
arguments;return function(e){for(var c=[],d=null,f=0;f<a.length;f++)if(null!=a[f]){try{d=a[f].call(this,e)}catch(n){throw new h.Exception(e);}c.push(d[0]);e=d[1]}return[c,e]}},all:function(){var a=a;return a.each(a.optional(arguments))},sequence:function(a,e,c){e=e||f.rtoken(/^\s*/);c=c||null;return 1===a.length?a[0]:function(d){for(var f=null,n=null,l=[],p=0;p<a.length;p++){try{f=a[p].call(this,d)}catch(q){break}l.push(f[0]);try{n=e.call(this,f[1])}catch(s){n=null;break}d=n[1]}if(!f)throw new h.Exception(d);
|
||||
if(n)throw new h.Exception(n[1]);if(c)try{f=c.call(this,f[1])}catch(u){throw new h.Exception(f[1]);}return[l,f?f[1]:d]}},between:function(a,e,c){c=c||a;var d=f.each(f.ignore(a),e,f.ignore(c));return function(a){a=d.call(this,a);return[[a[0][0],r[0][2]],a[1]]}},list:function(a,e,c){e=e||f.rtoken(/^\s*/);c=c||null;return a instanceof Array?f.each(f.product(a.slice(0,-1),f.ignore(e)),a.slice(-1),f.ignore(c)):f.each(f.many(f.each(a,f.ignore(e))),px,f.ignore(c))},set:function(a,e,c){e=e||f.rtoken(/^\s*/);
|
||||
c=c||null;return function(d){for(var k=null,n=k=null,l=null,p=[[],d],q=!1,s=0;s<a.length;s++){k=n=null;q=1===a.length;try{k=a[s].call(this,d)}catch(u){continue}l=[[k[0]],k[1]];if(0<k[1].length&&!q)try{n=e.call(this,k[1])}catch(v){q=!0}else q=!0;q||0!==n[1].length||(q=!0);if(!q){k=[];for(q=0;q<a.length;q++)s!==q&&k.push(a[q]);k=f.set(k,e).call(this,n[1]);0<k[0].length&&(l[0]=l[0].concat(k[0]),l[1]=k[1])}l[1].length<p[1].length&&(p=l);if(0===p[1].length)break}if(0===p[0].length)return p;if(c){try{n=
|
||||
c.call(this,p[1])}catch(w){throw new h.Exception(p[1]);}p[1]=n[1]}return p}},forward:function(a,e){return function(c){return a[e].call(this,c)}},replace:function(a,e){return function(c){c=a.call(this,c);return[e,c[1]]}},process:function(a,e){return function(c){c=a.call(this,c);return[e.call(this,c[0]),c[1]]}},min:function(a,e){return function(c){var d=e.call(this,c);if(d[0].length<a)throw new h.Exception(c);return d}}},d=function(a){return function(){var e=null,c=[],d;1<arguments.length?e=Array.prototype.slice.call(arguments):
|
||||
arguments[0]instanceof Array&&(e=arguments[0]);if(e){if(d=e.shift(),0<d.length)return e.unshift(d[void 0]),c.push(a.apply(null,e)),e.shift(),c}else return a.apply(null,arguments)}},c="optional not ignore cache".split(/\s/),a=0;a<c.length;a++)f[c[a]]=d(f[c[a]]);d=function(a){return function(){return arguments[0]instanceof Array?a.apply(null,arguments[0]):a.apply(null,arguments)}};c="each any all".split(/\s/);for(a=0;a<c.length;a++)f[c[a]]=d(f[c[a]])})();
|
||||
(function(){var h=Date,f=function(c){for(var a=[],b=0;b<c.length;b++)c[b]instanceof Array?a=a.concat(f(c[b])):c[b]&&a.push(c[b]);return a},d=function(){if(this.meridian&&(this.hour||0===this.hour)){if("a"===this.meridian&&11<this.hour&&Date.Config.strict24hr)throw"Invalid hour and meridian combination";if("p"===this.meridian&&12>this.hour&&Date.Config.strict24hr)throw"Invalid hour and meridian combination";"p"===this.meridian&&12>this.hour?this.hour+=12:"a"===this.meridian&&12===this.hour&&(this.hour=
|
||||
0)}};h.Translator={hour:function(c){return function(){this.hour=Number(c)}},minute:function(c){return function(){this.minute=Number(c)}},second:function(c){return function(){this.second=Number(c)}},secondAndMillisecond:function(c){return function(){var a=c.match(/^([0-5][0-9])\.([0-9]{1,3})/);this.second=Number(a[1]);this.millisecond=Number(a[2])}},meridian:function(c){return function(){this.meridian=c.slice(0,1).toLowerCase()}},timezone:function(c){return function(){var a=c.replace(/[^\d\+\-]/g,
|
||||
"");a.length?this.timezoneOffset=Number(a):this.timezone=c.toLowerCase()}},day:function(c){var a=c[0];return function(){this.day=Number(a.match(/\d+/)[0]);if(1>this.day)throw"invalid day";}},month:function(c){return function(){this.month=3===c.length?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(c)/4:Number(c)-1;if(0>this.month)throw"invalid month";}},year:function(c){return function(){var a=Number(c);this.year=2<c.length?a:a+(a+2E3<Date.CultureInfo.twoDigitYearMax?2E3:1900)}},rday:function(c){return function(){switch(c){case "yesterday":this.days=
|
||||
-1;break;case "tomorrow":this.days=1;break;case "today":this.days=0;break;case "now":this.days=0,this.now=!0}}},finishExact:function(c){c=c instanceof Array?c:[c];for(var a=0;a<c.length;a++)c[a]&&c[a].call(this);c=new Date;!this.hour&&!this.minute||this.month||this.year||this.day||(this.day=c.getDate());this.year||(this.year=c.getFullYear());this.month||0===this.month||(this.month=c.getMonth());this.day||(this.day=1);this.hour||(this.hour=0);this.minute||(this.minute=0);this.second||(this.second=
|
||||
0);this.millisecond||(this.millisecond=0);d.call(this);if(this.day>h.getDaysInMonth(this.year,this.month))throw new RangeError(this.day+" is not a valid value for days.");c=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.millisecond);100>this.year&&c.setFullYear(this.year);this.timezone?c.set({timezone:this.timezone}):this.timezoneOffset&&c.set({timezoneOffset:this.timezoneOffset});return c},finish:function(c){var a,b,e;c=c instanceof Array?f(c):[c];if(0===c.length)return null;
|
||||
for(a=0;a<c.length;a++)"function"===typeof c[a]&&c[a].call(this);if(!this.now||this.unit||this.operator)c=this.now||-1!=="hour minute second".indexOf(this.unit)?new Date:h.today();else return new Date;a=!!(this.days&&null!==this.days||this.orient||this.operator);b="past"===this.orient||"subtract"===this.operator?-1:1;this.month&&"week"===this.unit&&(this.value=this.month+1,delete this.month,delete this.day);!this.month&&0!==this.month||-1==="year day hour minute second".indexOf(this.unit)||(this.value||
|
||||
(this.value=this.month+1),this.month=null,a=!0);a||!this.weekday||this.day||this.days||(e=Date[this.weekday](),this.day=e.getDate(),this.month||(this.month=e.getMonth()),this.year=e.getFullYear());if(a&&this.weekday&&"month"!==this.unit&&"week"!==this.unit){var g=c;e=b||1;this.unit="day";this.days=(g=h.getDayNumberFromName(this.weekday)-g.getDay())?(g+7*e)%7:7*e}!this.weekday||"week"===this.unit||this.day||this.days||(e=Date[this.weekday](),this.day=e.getDate(),e.getMonth()!==c.getMonth()&&(this.month=
|
||||
e.getMonth()));this.month&&"day"===this.unit&&this.operator&&(this.value||(this.value=this.month+1),this.month=null);null!=this.value&&null!=this.month&&null!=this.year&&(this.day=1*this.value);this.month&&!this.day&&this.value&&(c.set({day:1*this.value}),a||(this.day=1*this.value));this.month||!this.value||"month"!==this.unit||this.now||(this.month=this.value,a=!0);a&&(this.month||0===this.month)&&"year"!==this.unit&&(e=b||1,this.unit="month",this.months=(g=this.month-c.getMonth())?(g+12*e)%12:12*
|
||||
e,this.month=null);this.unit||(this.unit="day");if(!this.value&&this.operator&&null!==this.operator&&this[this.unit+"s"]&&null!==this[this.unit+"s"])this[this.unit+"s"]=this[this.unit+"s"]+("add"===this.operator?1:-1)+(this.value||0)*b;else if(null==this[this.unit+"s"]||null!=this.operator)this.value||(this.value=1),this[this.unit+"s"]=this.value*b;d.call(this);!this.month&&0!==this.month||this.day||(this.day=1);if(!this.orient&&!this.operator&&"week"===this.unit&&this.value&&!this.day&&!this.month)return Date.today().setWeek(this.value);
|
||||
if("week"===this.unit&&this.weeks&&!this.day&&!this.month)return c=Date[void 0!==this.weekday?this.weekday:"today"]().addWeeks(this.weeks),this.now&&c.setTimeToNow(),c;a&&this.timezone&&this.day&&this.days&&(this.day=this.days);a?c.add(this):c.set(this);this.timezone&&(this.timezone=this.timezone.toUpperCase(),a=h.getTimezoneOffset(this.timezone),c.hasDaylightSavingTime()&&(b=h.getTimezoneAbbreviation(a,c.isDaylightSavingTime()),b!==this.timezone&&(c.isDaylightSavingTime()?c.addHours(-1):c.addHours(1))),
|
||||
c.setTimezoneOffset(a));return c}}})();
|
||||
(function(){var h=Date;h.Grammar={};var f=h.Parsing.Operators,d=h.Grammar,c=h.Translator,a;a=function(){return f.each(f.any.apply(null,arguments),f.not(d.ctoken2("timeContext")))};d.datePartDelimiter=f.rtoken(/^([\s\-\.\,\/\x27]+)/);d.timePartDelimiter=f.stoken(":");d.whiteSpace=f.rtoken(/^\s*/);d.generalDelimiter=f.rtoken(/^(([\s\,]|at|@|on)+)/);var b={};d.ctoken=function(a){var c=b[a];if(!c){for(var c=Date.CultureInfo.regexPatterns,e=a.split(/\s+/),d=[],g=0;g<e.length;g++)d.push(f.replace(f.rtoken(c[e[g]]),
|
||||
e[g]));c=b[a]=f.any.apply(null,d)}return c};d.ctoken2=function(a){return f.rtoken(Date.CultureInfo.regexPatterns[a])};var e=function(a,b,c,e){d[a]=e?f.cache(f.process(f.each(f.rtoken(b),f.optional(d.ctoken2(e))),c)):f.cache(f.process(f.rtoken(b),c))},g=function(a,b){return f.cache(f.process(d.ctoken2(a),b))},m={},k=function(a){m[a]=m[a]||d.format(a)[0];return m[a]};d.allformats=function(a){var b=[];if(a instanceof Array)for(var c=0;c<a.length;c++)b.push(k(a[c]));else b.push(k(a));return b};d.formats=
|
||||
function(a){if(a instanceof Array){for(var b=[],c=0;c<a.length;c++)b.push(k(a[c]));return f.any.apply(null,b)}return k(a)};var n={timeFormats:function(){var a,b="h hh H HH m mm s ss ss.s z zz".split(" "),h=[/^(0[0-9]|1[0-2]|[1-9])/,/^(0[0-9]|1[0-2])/,/^([0-1][0-9]|2[0-3]|[0-9])/,/^([0-1][0-9]|2[0-3])/,/^([0-5][0-9]|[0-9])/,/^[0-5][0-9]/,/^([0-5][0-9]|[0-9])/,/^[0-5][0-9]/,/^[0-5][0-9]\.[0-9]{1,3}/,/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/,/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/],m=[c.hour,
|
||||
c.hour,c.hour,c.hour,c.minute,c.minute,c.second,c.second,c.secondAndMillisecond,c.timezone,c.timezone];for(a=0;a<b.length;a++)e(b[a],h[a],m[a]);d.hms=f.cache(f.sequence([d.H,d.m,d.s],d.timePartDelimiter));d.t=g("shortMeridian",c.meridian);d.tt=g("longMeridian",c.meridian);d.zzz=g("timezone",c.timezone);d.timeSuffix=f.each(f.ignore(d.whiteSpace),f.set([d.tt,d.zzz]));d.time=f.each(f.optional(f.ignore(f.stoken("T"))),d.hms,d.timeSuffix)},dateFormats:function(){var b=function(){return f.set(arguments,
|
||||
d.datePartDelimiter)},g,h="d dd M MM y yy yyy yyyy".split(" "),m=[/^([0-2]\d|3[0-1]|\d)/,/^([0-2]\d|3[0-1])/,/^(1[0-2]|0\d|\d)/,/^(1[0-2]|0\d)/,/^(\d+)/,/^(\d\d)/,/^(\d\d?\d?\d?)/,/^(\d\d\d\d)/],n=[c.day,c.day,c.month,c.month,c.year,c.year,c.year,c.year],k=["ordinalSuffix","ordinalSuffix"];for(g=0;g<h.length;g++)e(h[g],m[g],n[g],k[g]);d.MMM=d.MMMM=f.cache(f.process(d.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),c.month));d.ddd=d.dddd=f.cache(f.process(d.ctoken("sun mon tue wed thu fri sat"),
|
||||
function(a){return function(){this.weekday=a}}));d.day=a(d.d,d.dd);d.month=a(d.M,d.MMM);d.year=a(d.yyyy,d.yy);d.mdy=b(d.ddd,d.month,d.day,d.year);d.ymd=b(d.ddd,d.year,d.month,d.day);d.dmy=b(d.ddd,d.day,d.month,d.year);d.date=function(a){return(d[Date.CultureInfo.dateElementOrder]||d.mdy).call(this,a)}},relative:function(){d.orientation=f.process(d.ctoken("past future"),function(a){return function(){this.orient=a}});d.operator=f.process(d.ctoken("add subtract"),function(a){return function(){this.operator=
|
||||
a}});d.rday=f.process(d.ctoken("yesterday tomorrow today now"),c.rday);d.unit=f.process(d.ctoken("second minute hour day week month year"),function(a){return function(){this.unit=a}})}};d.buildGrammarFormats=function(){b={};n.timeFormats();n.dateFormats();n.relative();d.value=f.process(f.rtoken(/^([-+]?\d+)?(st|nd|rd|th)?/),function(a){return function(){this.value=a.replace(/\D/g,"")}});d.expression=f.set([d.rday,d.operator,d.value,d.unit,d.orientation,d.ddd,d.MMM]);d.format=f.process(f.many(f.any(f.process(f.rtoken(/^(dd?d?d?(?!e)|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),
|
||||
function(a){if(d[a])return d[a];throw h.Parsing.Exception(a);}),f.process(f.rtoken(/^[^dMyhHmstz]+/),function(a){return f.ignore(f.stoken(a))}))),function(a){return f.process(f.each.apply(null,a),c.finishExact)});d._start=f.process(f.set([d.date,d.time,d.expression],d.generalDelimiter,d.whiteSpace),c.finish)};d.buildGrammarFormats();d._formats=d.formats('"yyyy-MM-ddTHH:mm:ssZ";yyyy-MM-ddTHH:mm:ss.sz;yyyy-MM-ddTHH:mm:ssZ;yyyy-MM-ddTHH:mm:ssz;yyyy-MM-ddTHH:mm:ss;yyyy-MM-ddTHH:mmZ;yyyy-MM-ddTHH:mmz;yyyy-MM-ddTHH:mm;ddd, MMM dd, yyyy H:mm:ss tt;ddd MMM d yyyy HH:mm:ss zzz;MMddyyyy;ddMMyyyy;Mddyyyy;ddMyyyy;Mdyyyy;dMyyyy;yyyy;Mdyy;dMyy;d'.split(";"));
|
||||
d.start=function(a){try{var b=d._formats.call({},a);if(0===b[1].length)return b}catch(c){}return d._start.call({},a)}})();
|
||||
(function(){var h=Date,f={removeOrds:function(d){return d=(ords=d.match(/\b(\d+)(?:st|nd|rd|th)\b/))&&2===ords.length?d.replace(ords[0],ords[1]):d},grammarParser:function(d){var c=null;try{c=h.Grammar.start.call({},d.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"))}catch(a){return null}return 0===c[1].length?c[0]:null},nativeFallback:function(d){var c;try{return(c=Date._parse(d))||0===c?new Date(c):null}catch(a){return null}}};h._parse||(h._parse=h.parse);h.parse=function(d){var c;if(!d)return null;if(d instanceof
|
||||
Date)return d.clone();4<=d.length&&"0"!==d.charAt(0)&&"+"!==d.charAt(0)&&"-"!==d.charAt(0)&&(c=h.Parsing.ISO.parse(d)||h.Parsing.Numeric.parse(d));if(c instanceof Date&&!isNaN(c.getTime()))return c;d=h.Parsing.Normalizer.parse(f.removeOrds(d));c=f.grammarParser(d);return null!==c?c:f.nativeFallback(d)};Date.getParseFunction=function(d){var c=Date.Grammar.allformats(d);return function(a){for(var b=null,e=0;e<c.length;e++){try{b=c[e].call({},a)}catch(d){continue}if(0===b[1].length)return b[0]}return null}};
|
||||
h.parseExact=function(d,c){return h.getParseFunction(c)(d)}})();
|
||||
(function(){var h=Date,f=h.prototype,d=function(a,b){b||(b=2);return("000"+a).slice(-1*b)},c={d:"dd","%d":"dd",D:"ddd","%a":"ddd",j:"dddd",l:"dddd","%A":"dddd",S:"S",F:"MMMM","%B":"MMMM",m:"MM","%m":"MM",M:"MMM","%b":"MMM","%h":"MMM",n:"M",Y:"yyyy","%Y":"yyyy",y:"yy","%y":"yy",g:"h","%I":"h",G:"H",h:"hh",H:"HH","%H":"HH",i:"mm","%M":"mm",s:"ss","%S":"ss","%r":"hh:mm tt","%R":"H:mm","%T":"H:mm:ss","%X":"t","%x":"d","%e":"d","%D":"MM/dd/yy","%n":"\\n","%t":"\\t",e:"z",T:"z","%z":"z","%Z":"z",Z:"ZZ",
|
||||
N:"u",w:"u","%w":"u",W:"W","%V":"W"},a={substitutes:function(a){return c[a]},interpreted:function(a,b){var c;switch(a){case "%u":return b.getDay()+1;case "z":return b.getOrdinalNumber();case "%j":return d(b.getOrdinalNumber(),3);case "%U":c=b.clone().set({month:0,day:1}).addDays(-1).moveToDayOfWeek(0);var f=b.clone().addDays(1).moveToDayOfWeek(0,-1);return f<c?"00":d((f.getOrdinalNumber()-c.getOrdinalNumber())/7+1);case "%W":return d(b.getWeek());case "t":return h.getDaysInMonth(b.getFullYear(),b.getMonth());
|
||||
case "o":case "%G":return b.setWeek(b.getISOWeek()).toString("yyyy");case "%g":return b._format("%G").slice(-2);case "a":case "%p":return t("tt").toLowerCase();case "A":return t("tt").toUpperCase();case "u":return d(b.getMilliseconds(),3);case "I":return b.isDaylightSavingTime()?1:0;case "O":return b.getUTCOffset();case "P":return c=b.getUTCOffset(),c.substring(0,c.length-2)+":"+c.substring(c.length-2);case "B":return c=new Date,Math.floor((3600*c.getHours()+60*c.getMinutes()+c.getSeconds()+60*(c.getTimezoneOffset()+
|
||||
60))/86.4);case "c":return b.toISOString().replace(/\"/g,"");case "U":return h.strtotime("now");case "%c":return t("d")+" "+t("t");case "%C":return Math.floor(b.getFullYear()/100+1)}},shouldOverrideDefaults:function(a){switch(a){case "%e":return!0;default:return!1}},parse:function(b,c){var d,f=c||new Date;return(d=a.substitutes(b))?d:(d=a.interpreted(b,f))?d:b}};h.normalizeFormat=function(b,c){return b.replace(/(%|\\)?.|%%/g,function(b){return a.parse(b,c)})};h.strftime=function(a,b){return Date.parse(b)._format(a)};
|
||||
h.strtotime=function(a){a=h.parse(a);return Math.round(h.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate(),a.getUTCHours(),a.getUTCMinutes(),a.getUTCSeconds(),a.getUTCMilliseconds())/1E3)};var b=function(b){return function(c){var d=!1;if("\\"===c.charAt(0)||"%%"===c.substring(0,2))return c.replace("\\","").replace("%%","%");d=a.shouldOverrideDefaults(c);if(c=h.normalizeFormat(c,b))return b.toString(c,d)}};f._format=function(a){var c=b(this);return a?a.replace(/(%|\\)?.|%%/g,c):this._toString()};
|
||||
f.format||(f.format=f._format)})();
|
||||
(function(){var h=function(c){return function(){return this[c]}},f=function(c){return function(a){this[c]=a;return this}},d=function(c,a,b,e,f){if(1===arguments.length&&"number"===typeof c){var h=0>c?-1:1,k=Math.abs(c);this.setDays(Math.floor(k/864E5)*h);k%=864E5;this.setHours(Math.floor(k/36E5)*h);k%=36E5;this.setMinutes(Math.floor(k/6E4)*h);k%=6E4;this.setSeconds(Math.floor(k/1E3)*h);this.setMilliseconds(k%1E3*h)}else this.set(c,a,b,e,f);this.getTotalMilliseconds=function(){return 864E5*this.getDays()+
|
||||
36E5*this.getHours()+6E4*this.getMinutes()+1E3*this.getSeconds()};this.compareTo=function(a){var b=new Date(1970,1,1,this.getHours(),this.getMinutes(),this.getSeconds());a=null===a?new Date(1970,1,1,0,0,0):new Date(1970,1,1,a.getHours(),a.getMinutes(),a.getSeconds());return b<a?-1:b>a?1:0};this.equals=function(a){return 0===this.compareTo(a)};this.add=function(a){return null===a?this:this.addSeconds(a.getTotalMilliseconds()/1E3)};this.subtract=function(a){return null===a?this:this.addSeconds(-a.getTotalMilliseconds()/
|
||||
1E3)};this.addDays=function(a){return new d(this.getTotalMilliseconds()+864E5*a)};this.addHours=function(a){return new d(this.getTotalMilliseconds()+36E5*a)};this.addMinutes=function(a){return new d(this.getTotalMilliseconds()+6E4*a)};this.addSeconds=function(a){return new d(this.getTotalMilliseconds()+1E3*a)};this.addMilliseconds=function(a){return new d(this.getTotalMilliseconds()+a)};this.get12HourHour=function(){return 12<this.getHours()?this.getHours()-12:0===this.getHours()?12:this.getHours()};
|
||||
this.getDesignator=function(){return 12>this.getHours()?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator};this.toString=function(a){this._toString=function(){return null!==this.getDays()&&0<this.getDays()?this.getDays()+"."+this.getHours()+":"+this.p(this.getMinutes())+":"+this.p(this.getSeconds()):this.getHours()+":"+this.p(this.getMinutes())+":"+this.p(this.getSeconds())};this.p=function(a){return 2>a.toString().length?"0"+a:a};var b=this;return a?a.replace(/dd?|HH?|hh?|mm?|ss?|tt?/g,
|
||||
function(a){switch(a){case "d":return b.getDays();case "dd":return b.p(b.getDays());case "H":return b.getHours();case "HH":return b.p(b.getHours());case "h":return b.get12HourHour();case "hh":return b.p(b.get12HourHour());case "m":return b.getMinutes();case "mm":return b.p(b.getMinutes());case "s":return b.getSeconds();case "ss":return b.p(b.getSeconds());case "t":return(12>b.getHours()?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator).substring(0,1);case "tt":return 12>b.getHours()?Date.CultureInfo.amDesignator:
|
||||
Date.CultureInfo.pmDesignator}}):this._toString()};return this};(function(c,a){for(var b=0;b<a.length;b++){var e=a[b],d=e.slice(0,1).toUpperCase()+e.slice(1);c.prototype[e]=0;c.prototype["get"+d]=h(e);c.prototype["set"+d]=f(e)}})(d,"years months days hours minutes seconds milliseconds".split(" ").slice(2));d.prototype.set=function(c,a,b,e,d){this.setDays(c||this.getDays());this.setHours(a||this.getHours());this.setMinutes(b||this.getMinutes());this.setSeconds(e||this.getSeconds());this.setMilliseconds(d||
|
||||
this.getMilliseconds())};Date.prototype.getTimeOfDay=function(){return new d(0,this.getHours(),this.getMinutes(),this.getSeconds(),this.getMilliseconds())};Date.TimeSpan=d;"undefined"!==typeof window&&(window.TimeSpan=d)})();
|
||||
(function(){var h=function(a){return function(){return this[a]}},f=function(a){return function(b){this[a]=b;return this}},d=function(a,b,c,d){function f(){b.addMonths(-a);d.months++;12===d.months&&(d.years++,d.months=0)}if(1===a)for(;b>c;)f();else for(;b<c;)f();d.months--;d.months*=a;d.years*=a},c=function(a,b,c,f,h,k,n){if(7===arguments.length)this.set(a,b,c,f,h,k,n);else if(2===arguments.length&&arguments[0]instanceof Date&&arguments[1]instanceof Date){var l=arguments[0].clone(),p=arguments[1].clone(),
|
||||
q=l>p?1:-1;this.dates={start:arguments[0].clone(),end:arguments[1].clone()};d(q,l,p,this);var s=!1===(l.isDaylightSavingTime()===p.isDaylightSavingTime());s&&1===q?l.addHours(-1):s&&l.addHours(1);l=p-l;0!==l&&(l=new TimeSpan(l),this.set(this.years,this.months,l.getDays(),l.getHours(),l.getMinutes(),l.getSeconds(),l.getMilliseconds()))}return this};(function(a,b){for(var c=0;c<b.length;c++){var d=b[c],m=d.slice(0,1).toUpperCase()+d.slice(1);a.prototype[d]=0;a.prototype["get"+m]=h(d);a.prototype["set"+
|
||||
m]=f(d)}})(c,"years months days hours minutes seconds milliseconds".split(" "));c.prototype.set=function(a,b,c,d,f,h,n){this.setYears(a||this.getYears());this.setMonths(b||this.getMonths());this.setDays(c||this.getDays());this.setHours(d||this.getHours());this.setMinutes(f||this.getMinutes());this.setSeconds(h||this.getSeconds());this.setMilliseconds(n||this.getMilliseconds())};Date.TimePeriod=c;"undefined"!==typeof window&&(window.TimePeriod=c)})();
|
||||
@@ -96,6 +96,13 @@ function preparePage () {
|
||||
}
|
||||
}
|
||||
|
||||
function getLocalTime(datetime_string, format) {
|
||||
if (format === undefined) { format = 'Y-m-d %H:%M:%S O'; }
|
||||
|
||||
var date = new Date(datetime_string);
|
||||
return date.format(format);
|
||||
}
|
||||
|
||||
function flashNotice(type, notice, button_label, button_function, button_type) {
|
||||
// accepted types: info, success, warn, error
|
||||
nested_button_html = '';
|
||||
@@ -155,6 +162,16 @@ $(document).ready(function() {
|
||||
}
|
||||
}
|
||||
|
||||
// Set time in local time
|
||||
if (showLocalTime) {
|
||||
$(function() {
|
||||
$('time').each(function() {
|
||||
var datetime = $(this).attr('datetime');
|
||||
var format = $(this).data('format');
|
||||
$(this).html(getLocalTime(datetime, format));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if ($('.minibutton-upload-page').length) {
|
||||
new ClipboardJS('#ClipboardJSlink');
|
||||
@@ -574,8 +591,9 @@ $(document).ready(function() {
|
||||
url: routePath('last_commit_info'),
|
||||
data: {path: $("#page-info-toggle").data('pagepath')},
|
||||
success: function ( data ) {
|
||||
var date = showLocalTime ? getLocalTime(data.date) : data.date;
|
||||
$("#last-edit").next(".dotted-spinner").toggleClass('hidden');
|
||||
$("#last-edit-in-progress").html('Last edited by <b>' + data.author + '</b>, ' + data.date);
|
||||
$("#last-edit-in-progress").html('Last edited by <b>' + data.author + '</b>, ' + date);
|
||||
}
|
||||
});
|
||||
$("#last-edit").next(".dotted-spinner").toggleClass('hidden')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<h1 class="header-title text-center text-md-left py-4">
|
||||
{{message}}
|
||||
</h1>
|
||||
{{author}} commited {{authored_date}}
|
||||
{{author}} commited <time datetime="{{datetime}}">{{authored_date}}</time>
|
||||
<span class="px-2 float-right">commit <code>{{version}}</code></span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<li class="Box-row border-top Box-row--hover-gray d-flex flex-items-center">
|
||||
<span class="pr-2"><input class="checkbox" type="checkbox" name="versions[]" value="{{id}}"></span>
|
||||
<span class="float-left col-2" id="user-icons">{{>author_template}}</span>
|
||||
<span class="flex-auto col-1 text-gray-light">{{date}}</span>
|
||||
<time class="flex-auto col-1 text-gray-light" datetime="{{datetime}}" data-format="{{date_format}}">{{date}}</time>
|
||||
<span class="flex-auto col-5">{{message}}</span>
|
||||
<span class="pl-4 float-right">
|
||||
<a href="{{href}}" class="btn btn-outline text-mono">{{id7}}</a>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{{#versions}}
|
||||
<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="flex-auto col-1 text-gray-light">{{date}}</span>
|
||||
<time class="flex-auto col-1 text-gray-light" datetime="{{datetime}}" data-format="{{date_format}}">{{date}}</time>
|
||||
<span class="flex-auto col-5">{{message}}<br/>
|
||||
{{#files}}
|
||||
<span class="flex-auto col-2">{{#renamed}}{{renamed}} -> {{/renamed}}<a href="{{link}}">{{file}}</a></span><br/>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<script>
|
||||
var criticMarkup = '{{critic_markup}}';
|
||||
var baseUrl = '{{base_url}}';
|
||||
var showLocalTime = {{{show_local_time}}};
|
||||
var uploadDest = 'uploads';
|
||||
var perPageUploads = '{{per_page_uploads}}';
|
||||
if (perPageUploads == 'true') {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
{{#history}}
|
||||
<a
|
||||
class="btn BtnGroup-item btn-sm hide-sm hide-md"
|
||||
href="{{history_path}}/{{escaped_url_path}}"
|
||||
href="{{history_path}}/{{escaped_url_path}}/{{version}}"
|
||||
id="minibutton-history"
|
||||
>
|
||||
History
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
{{/preview}}
|
||||
{{/historical}}
|
||||
{{#historical}}
|
||||
<p>This version of the page was edited by <b>{{author}}</b> at {{date}}. <a href="{{full_url_path}}">View the most recent version.</a></p>
|
||||
<p>This version of the page was edited by <b>{{author}}</b> at <time datetime="{{datetime}}" data-format="{{date_format}}">{{date}}</time>. <a href="{{full_url_path}}">View the most recent version.</a></p>
|
||||
{{/historical}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ module Precious
|
||||
@commit.authored_date
|
||||
end
|
||||
|
||||
def datetime
|
||||
authored_date.utc.iso8601
|
||||
end
|
||||
|
||||
def message
|
||||
@commit.message
|
||||
end
|
||||
|
||||
@@ -42,7 +42,7 @@ module Precious
|
||||
end
|
||||
|
||||
def fill_argument_content(i18n_key, i18n_value)
|
||||
i18n_value.gsub!(YAML_VARIABLE_REGEXP) do |argument|
|
||||
i18n_value = i18n_value.gsub(YAML_VARIABLE_REGEXP) do |argument|
|
||||
method_name = argument.gsub(/[^\w]/, '')
|
||||
|
||||
next if method_name.nil?
|
||||
|
||||
+17
-12
@@ -1,6 +1,8 @@
|
||||
module Precious
|
||||
module Views
|
||||
class History < Layout
|
||||
DATE_FORMAT = '%B %d, %Y'
|
||||
|
||||
include HasPage
|
||||
include Pagination
|
||||
include HasUserIcons
|
||||
@@ -18,18 +20,21 @@ module Precious
|
||||
@versions.map do |v|
|
||||
i -= 1
|
||||
filename = path_for_version(v.tracked_pathname)
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:href => page_route("gollum/commit/#{v.id}"),
|
||||
:href_page => page_route("#{filename}/#{v.id}"),
|
||||
:num => i,
|
||||
:selected => @page.version.id == v.id,
|
||||
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
||||
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
||||
:date => v.authored_date.strftime("%B %d, %Y"),
|
||||
:user_icon => self.user_icon_code(v.author.email),
|
||||
:filename => filename,
|
||||
:date_full => v.authored_date,
|
||||
authored_date = v.authored_date
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:href => page_route("gollum/commit/#{v.id}"),
|
||||
:href_page => page_route("#{filename}/#{v.id}"),
|
||||
:num => i,
|
||||
:selected => @page.version.id == v.id,
|
||||
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
||||
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
||||
:date_full => authored_date,
|
||||
:date => authored_date.strftime(DATE_FORMAT),
|
||||
:datetime => authored_date.utc.iso8601,
|
||||
:date_format => DATE_FORMAT,
|
||||
:user_icon => self.user_icon_code(v.author.email),
|
||||
:filename => filename
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module Precious
|
||||
module Views
|
||||
class LatestChanges < Layout
|
||||
DATE_FORMAT = '%B %d, %Y'
|
||||
|
||||
include Pagination
|
||||
include HasUserIcons
|
||||
|
||||
@@ -14,16 +16,19 @@ module Precious
|
||||
i = @versions.size + 1
|
||||
@versions.map do |v|
|
||||
i -= 1
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:href => page_route("gollum/commit/#{v.id}"),
|
||||
:num => i,
|
||||
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
||||
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
||||
:date => v.authored_date.strftime("%B %d, %Y"),
|
||||
:user_icon => self.user_icon_code(v.author.email),
|
||||
:date_full => v.authored_date,
|
||||
:files => v.stats.files.map { |f|
|
||||
authored_date = v.authored_date
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:href => page_route("gollum/commit/#{v.id}"),
|
||||
:num => i,
|
||||
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
||||
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
||||
:date_full => authored_date,
|
||||
:date => authored_date.strftime(DATE_FORMAT),
|
||||
:datetime => authored_date.utc.iso8601,
|
||||
:date_format => DATE_FORMAT,
|
||||
:user_icon => self.user_icon_code(v.author.email),
|
||||
:files => v.stats.files.map { |f|
|
||||
new_path = extract_page_dir(f[:new_file])
|
||||
{ :file => new_path,
|
||||
:link => "#{page_route(new_path)}/#{v.id}",
|
||||
|
||||
@@ -67,6 +67,10 @@ module Precious
|
||||
@per_page_uploads
|
||||
end
|
||||
|
||||
def show_local_time
|
||||
@show_local_time ? 'true' : 'false'
|
||||
end
|
||||
|
||||
# Navigation bar
|
||||
def search
|
||||
false
|
||||
|
||||
@@ -4,7 +4,7 @@ module Precious
|
||||
include HasPage
|
||||
include HasMath
|
||||
|
||||
attr_reader :content, :page, :header, :footer, :preview, :historical
|
||||
attr_reader :content, :page, :header, :footer, :preview, :historical, :version
|
||||
|
||||
VALID_COUNTER_STYLES = ['decimal', 'decimal-leading-zero', 'arabic-indic', 'armenian', 'upper-armenian',
|
||||
'lower-armenian', 'bengali', 'cambodian', 'khmer', 'cjk-decimal', 'devanagari', 'georgian', 'gujarati', 'gurmukhi',
|
||||
@@ -49,10 +49,22 @@ module Precious
|
||||
first.author.name.respond_to?(:force_encoding) ? first.author.name.force_encoding('UTF-8') : first.author.name
|
||||
end
|
||||
|
||||
def date
|
||||
def date_full
|
||||
first = @version ? page.version : page.last_version
|
||||
return Time.now.strftime(DATE_FORMAT) unless first
|
||||
first.authored_date.strftime(DATE_FORMAT)
|
||||
return Time.now unless first
|
||||
first.authored_date
|
||||
end
|
||||
|
||||
def date
|
||||
date_full.strftime(DATE_FORMAT)
|
||||
end
|
||||
|
||||
def datetime
|
||||
date_full.utc.iso8601
|
||||
end
|
||||
|
||||
def date_format
|
||||
DATE_FORMAT
|
||||
end
|
||||
|
||||
def noindex
|
||||
|
||||
@@ -11,9 +11,13 @@ module Precious
|
||||
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
|
||||
priority =
|
||||
if template_priority_path
|
||||
File.join(template_priority_path, "#{name}.#{template_extension}")
|
||||
end
|
||||
|
||||
priority && File.exist?(priority) ? priority : default
|
||||
end
|
||||
|
||||
# Method should track lib/mustache/settings.rb from Mustache project.
|
||||
|
||||
Binary file not shown.
@@ -3,3 +3,5 @@
|
||||
f403b791119f8232b7cb0ba455c624ac6435f433 ed6c9f63b98acf73c25b5ffbb38da557d3682023 bootstraponline <cafe@bootstraponline.com> 1336421777 -0600 commit: Add header.
|
||||
ed6c9f63b98acf73c25b5ffbb38da557d3682023 084a558a1fb3cded23129e2dfad3a17d07d73fd3 Daniel Kimsey <dekimsey@ufl.edu> 1354899095 -0500 push
|
||||
084a558a1fb3cded23129e2dfad3a17d07d73fd3 02796b1450691f90db5d6dc6a816a4980ce80d07 Dawa Ometto <dawa.ometto@phil.uu.nl> 1538516954 +0200 push
|
||||
02796b1450691f90db5d6dc6a816a4980ce80d07 db8b297cf5a31b46ac24500edfdbd0d3d8eed4eb Nikita Ivanov <nikita.vyach.ivanov@gmail.com> 1640368693 +0500 commit: Created C (markdown)
|
||||
db8b297cf5a31b46ac24500edfdbd0d3d8eed4eb c736e410f98df7a1173a540364dbb8a18274273e Nikita Ivanov <nikita.vyach.ivanov@gmail.com> 1640368721 +0500 commit: Deleted C.md
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
f403b791119f8232b7cb0ba455c624ac6435f433 ed6c9f63b98acf73c25b5ffbb38da557d3682023 bootstraponline <cafe@bootstraponline.com> 1336421777 -0600 commit: Add header.
|
||||
ed6c9f63b98acf73c25b5ffbb38da557d3682023 084a558a1fb3cded23129e2dfad3a17d07d73fd3 Daniel Kimsey <dekimsey@ufl.edu> 1354899095 -0500 push
|
||||
084a558a1fb3cded23129e2dfad3a17d07d73fd3 02796b1450691f90db5d6dc6a816a4980ce80d07 Dawa Ometto <dawa.ometto@phil.uu.nl> 1538516954 +0200 push
|
||||
02796b1450691f90db5d6dc6a816a4980ce80d07 db8b297cf5a31b46ac24500edfdbd0d3d8eed4eb Nikita Ivanov <nikita.vyach.ivanov@gmail.com> 1640368693 +0500 commit: Created C (markdown)
|
||||
db8b297cf5a31b46ac24500edfdbd0d3d8eed4eb c736e410f98df7a1173a540364dbb8a18274273e Nikita Ivanov <nikita.vyach.ivanov@gmail.com> 1640368721 +0500 commit: Deleted C.md
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
x¥ŽK
|
||||
Â0@]÷³Ê¤ù4A7n¼Ã$3±AÓJ‰ooñ
|
||||
.ß[<^œKÉ:‹»ºˆ€Öɸ€bY¥Á¡öI'Rh¢Ø8hSô¨4Só¢E¦
|
||||
|è†>&KZã(vÆ"
|
||||
'Œ¬Ù‹°‘ÐлŽó·üÈ•àºÒ4¯p˜~Ø®Šc›òt/”ŸmœË”3¨�ï;{ܲÍf·Ý*‡š‹<¥
|
||||
ù-üš…Q×
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
02796b1450691f90db5d6dc6a816a4980ce80d07
|
||||
c736e410f98df7a1173a540364dbb8a18274273e
|
||||
|
||||
+33
-13
@@ -1,18 +1,20 @@
|
||||
require 'rubygems'
|
||||
require 'rack/test'
|
||||
require 'test/unit'
|
||||
require 'shoulda'
|
||||
require 'mocha/setup'
|
||||
require 'fileutils'
|
||||
require 'minitest/autorun'
|
||||
require 'minitest/reporters'
|
||||
require 'minitest/spec'
|
||||
require 'mocha/setup'
|
||||
require 'fileutils'
|
||||
require 'tmpdir'
|
||||
|
||||
# Silence locale validation warning
|
||||
require 'i18n'
|
||||
I18n.enforce_available_locales = false
|
||||
|
||||
MiniTest::Reporters.use!
|
||||
Minitest::Reporters.use! [
|
||||
Minitest::Reporters::DefaultReporter.new({color: true})
|
||||
]
|
||||
|
||||
dir = File.dirname(File.expand_path(__FILE__))
|
||||
$LOAD_PATH.unshift(File.join(dir, '..', 'lib'))
|
||||
@@ -62,14 +64,29 @@ def normal(text)
|
||||
text
|
||||
end
|
||||
|
||||
# test/spec/mini 3
|
||||
# http://gist.github.com/25455
|
||||
# chris@ozmm.org
|
||||
# file:lib/test/spec/mini.rb
|
||||
# The following configuration originates from this gist:
|
||||
|
||||
# http://gist.github.com/25455
|
||||
#
|
||||
# But it has been modified since it was first committed. It allows you to
|
||||
# write tests with an RSpec-like DSL:
|
||||
#
|
||||
# context "my test context" do
|
||||
# setup do
|
||||
# # My test setup
|
||||
# end
|
||||
#
|
||||
# teardown do
|
||||
# # My test teardown
|
||||
# end
|
||||
#
|
||||
# test "some functionality" do
|
||||
# assert true
|
||||
# end
|
||||
# end
|
||||
def context(*args, &block)
|
||||
return super unless (name = args.first) && block
|
||||
require 'test/unit'
|
||||
klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
|
||||
klass = Class.new(Minitest::Test) do
|
||||
def self.test(name, &block)
|
||||
define_method("test_#{name.gsub(/\W/, '_')}", &block) if block
|
||||
end
|
||||
@@ -85,10 +102,13 @@ def context(*args, &block)
|
||||
define_method(:teardown, &block)
|
||||
end
|
||||
end
|
||||
|
||||
(
|
||||
class << klass;
|
||||
self
|
||||
end).send(:define_method, :name) { name.gsub(/\W/, '_') }
|
||||
class << klass;
|
||||
self
|
||||
end
|
||||
).send(:define_method, :name) { name.gsub(/\W/, '_') }
|
||||
|
||||
$contexts << klass
|
||||
klass.class_eval &block
|
||||
end
|
||||
|
||||
+52
-32
@@ -3,84 +3,104 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||
|
||||
context "Precious::Views::Editing" do
|
||||
include Rack::Test::Methods
|
||||
|
||||
setup do
|
||||
@path = cloned_testpath('examples/revert.git')
|
||||
@path = cloned_testpath('examples/revert.git')
|
||||
Precious::App.set(:gollum_path, @path)
|
||||
Precious::App.set(:wiki_options, {allow_editing: true, allow_uploads: true})
|
||||
@wiki = Gollum::Wiki.new(@path)
|
||||
end
|
||||
|
||||
teardown do
|
||||
Precious::App.set(:wiki_options, {allow_editing: true, allow_uploads: true})
|
||||
FileUtils.rm_rf(@path)
|
||||
end
|
||||
|
||||
test "creating page is blocked" do
|
||||
Precious::App.set(:wiki_options, { allow_editing: false})
|
||||
post "/gollum/create", :content => 'abc', :page => "D",
|
||||
:format => 'markdown', :message => 'def'
|
||||
assert !last_response.ok?
|
||||
test 'creating pages is not blocked' do
|
||||
post '/gollum/create',
|
||||
content: 'abc',
|
||||
format: 'markdown',
|
||||
message: 'def',
|
||||
page: 'D'
|
||||
|
||||
page = @wiki.page('D')
|
||||
assert page.nil?
|
||||
assert_equal last_response.status, 302
|
||||
|
||||
refute_nil @wiki.page('D')
|
||||
end
|
||||
|
||||
test 'creating pages is blocked' do
|
||||
Precious::App.set(:wiki_options, {allow_editing: false, allow_uploads: false})
|
||||
|
||||
post '/gollum/create',
|
||||
content: 'abc',
|
||||
format: 'markdown',
|
||||
message: 'def',
|
||||
page: 'D'
|
||||
|
||||
assert last_response.body.include? 'Forbidden. This wiki is set to no-edit mode.'
|
||||
|
||||
refute last_response.ok?
|
||||
|
||||
assert_nil @wiki.page('D')
|
||||
end
|
||||
|
||||
test ".redirects.gollum file should not be accessible" do
|
||||
Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true })
|
||||
get '/.redirects.gollum'
|
||||
assert_match /Accessing this resource is not allowed/, last_response.body
|
||||
end
|
||||
|
||||
test ".redirects.gollum file should not be editable" do
|
||||
Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true })
|
||||
get '/gollum/edit/.redirects.gollum'
|
||||
assert_match /Changing this resource is not allowed/, last_response.body
|
||||
end
|
||||
|
||||
test "frontend links for editing are not blocked" do
|
||||
Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true })
|
||||
get '/A'
|
||||
|
||||
assert_match /Delete this Page/, last_response.body, "'Delete this Page' link is blocked in page template"
|
||||
assert_match /New/, last_response.body, "'New' button is blocked in page template"
|
||||
assert_match /Upload\b/, last_response.body, "'Upload' link is blocked in page template"
|
||||
assert_match /Rename/, last_response.body, "'Rename' link is blocked in page template"
|
||||
assert_match /Edit/, last_response.body, "'Edit' link is blocked in page template"
|
||||
assert last_response.body.include? "Delete this Page"
|
||||
assert last_response.body.include? "New"
|
||||
assert last_response.body.include? "<span>Upload</span>"
|
||||
assert last_response.body.include? "Rename"
|
||||
assert last_response.body.include? "Edit"
|
||||
|
||||
get '/gollum/overview'
|
||||
|
||||
assert_match /New/, last_response.body, "'New' link is blocked in pages template"
|
||||
assert last_response.body.include? "New"
|
||||
|
||||
get '/gollum/history/A'
|
||||
|
||||
assert_no_match /Edit/, last_response.body, "'Edit' link is not blocked in history template"
|
||||
refute last_response.body.include? "Edit"
|
||||
|
||||
get '/gollum/compare/A/fc66539528eb96f21b2bbdbf557788fe8a1196ac..b26b791cb7917c4f37dd9cb4d1e0efb24ac4d26f'
|
||||
get '/gollum/compare/A/fc665395..b26b791c'
|
||||
|
||||
assert_no_match /Edit Page/, last_response.body, "'Edit Page' link is not blocked in compare template"
|
||||
assert_match /Revert Changes/, last_response.body, "'Revert Changes' link is blocked in compare template"
|
||||
refute last_response.body.include? "Edit Page"
|
||||
|
||||
assert last_response.body.include? "Revert Changes"
|
||||
end
|
||||
|
||||
test "frontend links for editing blocked" do
|
||||
Precious::App.set(:wiki_options, { allow_editing: false })
|
||||
Precious::App.set(:wiki_options, {allow_editing: false, allow_uploads: false})
|
||||
|
||||
get '/A'
|
||||
|
||||
assert_no_match /Delete this Page/, last_response.body, "'Delete this Page' link not blocked in page template"
|
||||
assert_no_match /New/, last_response.body, "'New' button not blocked in page template"
|
||||
assert_no_match /Upload\b/, last_response.body, "'Upload' link not blocked in page template"
|
||||
assert_no_match /Rename/, last_response.body, "'Rename' link not blocked in page template"
|
||||
assert_no_match /Edit/, last_response.body, "'Edit' link not blocked in page template"
|
||||
refute last_response.body.include? "Delete this Page"
|
||||
refute last_response.body.include? "<span>Upload</span>"
|
||||
refute last_response.body.include? "Rename"
|
||||
refute last_response.body.include? "Edit"
|
||||
refute last_response.body.include? "New"
|
||||
|
||||
get '/gollum/overview'
|
||||
|
||||
assert_no_match /New/, last_response.body, "'New' link not blocked in pages template"
|
||||
refute last_response.body.include? "New"
|
||||
|
||||
get '/gollum/history/A'
|
||||
|
||||
assert_no_match /Edit/, last_response.body, "'Edit' link not blocked in history template"
|
||||
refute last_response.body.include? "Edit"
|
||||
|
||||
get '/gollum/compare/A/fc66539528eb96f21b2bbdbf557788fe8a1196ac..b26b791cb7917c4f37dd9cb4d1e0efb24ac4d26f'
|
||||
get '/gollum/compare/A/fc665395..b26b791c'
|
||||
|
||||
assert_no_match /Edit Page/, last_response.body, "'Edit Page' link not blocked in compare template"
|
||||
assert_no_match /Revert Changes/, last_response.body, "'Revert Changes' link not blocked in compare template"
|
||||
refute last_response.body.include? "Edit Page"
|
||||
refute last_response.body.include? "Revert Changes"
|
||||
end
|
||||
|
||||
def app
|
||||
|
||||
+78
-24
@@ -104,7 +104,7 @@ EOF
|
||||
page_2 = @wiki.page(page_1.name)
|
||||
assert_equal 'abc', page_2.raw_data
|
||||
assert_equal 'def', page_2.version.message
|
||||
assert_not_equal page_1.version.sha, page_2.version.sha
|
||||
refute_equal page_1.version.sha, page_2.version.sha
|
||||
end
|
||||
|
||||
test "edit page fails when page is outdated (edit collision)" do
|
||||
@@ -117,7 +117,7 @@ EOF
|
||||
@wiki.clear_cache
|
||||
page = @wiki.page('A')
|
||||
new_sha = page.sha
|
||||
assert_not_equal old_sha, new_sha
|
||||
refute_equal old_sha, new_sha
|
||||
|
||||
post "/gollum/edit/A", :content => 'def', :page => 'A',
|
||||
:format => page.format, :message => 'def', :etag => old_sha
|
||||
@@ -134,7 +134,7 @@ EOF
|
||||
page_2 = @wiki.page(page_1.name)
|
||||
assert_equal 'abc', page_2.raw_data
|
||||
assert_equal '[no message]', page_2.version.message
|
||||
assert_not_equal page_1.version.sha, page_2.version.sha
|
||||
refute_equal page_1.version.sha, page_2.version.sha
|
||||
end
|
||||
|
||||
test "edit page with slash" do
|
||||
@@ -165,13 +165,13 @@ EOF
|
||||
assert_equal 'header', header_2.raw_data
|
||||
assert_equal 'footer', foot_2.raw_data
|
||||
assert_equal 'def', foot_2.version.message
|
||||
assert_not_equal foot_1.version.sha, foot_2.version.sha
|
||||
assert_not_equal header_1.version.sha, header_2.version.sha
|
||||
refute_equal foot_1.version.sha, foot_2.version.sha
|
||||
refute_equal header_1.version.sha, header_2.version.sha
|
||||
|
||||
assert_equal 'sidebar', side_2.raw_data
|
||||
assert_equal 'def', side_2.version.message
|
||||
assert_not_equal side_1.version.sha, side_2.version.sha
|
||||
assert_equal commits+1, @wiki.repo.commits('master').size
|
||||
refute_equal side_1.version.sha, side_2.version.sha
|
||||
assert_equal commits, @wiki.repo.commits('master').size
|
||||
end
|
||||
|
||||
test "renames page" do
|
||||
@@ -187,7 +187,7 @@ EOF
|
||||
page_2 = @wiki.page('C')
|
||||
assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data
|
||||
assert_equal 'def', page_2.last_version.message
|
||||
assert_not_equal page_1.version.sha, page_2.version.sha
|
||||
refute_equal page_1.version.sha, page_2.version.sha
|
||||
end
|
||||
|
||||
test "rename preserves format" do
|
||||
@@ -222,7 +222,7 @@ EOF
|
||||
|
||||
test "renames page in subdirectory" do
|
||||
page_1 = @wiki.page("G/H")
|
||||
assert_not_equal page_1, nil
|
||||
refute_equal page_1, nil
|
||||
post "/gollum/rename/G/H", :rename => "/I/C", :message => 'def'
|
||||
|
||||
follow_redirect!
|
||||
@@ -234,12 +234,12 @@ EOF
|
||||
page_2 = @wiki.page('I/C')
|
||||
assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data
|
||||
assert_equal 'def', page_2.last_version.message
|
||||
assert_not_equal page_1.version.sha, page_2.version.sha
|
||||
refute_equal page_1.version.sha, page_2.version.sha
|
||||
end
|
||||
|
||||
test "renames page relative in subdirectory" do
|
||||
page_1 = @wiki.page("G/H")
|
||||
assert_not_equal page_1, nil
|
||||
refute_equal page_1, nil
|
||||
post "/gollum/rename/G/H", :rename => "K/C", :message => 'def'
|
||||
|
||||
follow_redirect!
|
||||
@@ -251,7 +251,7 @@ EOF
|
||||
page_2 = @wiki.page('G/K/C')
|
||||
assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data
|
||||
assert_equal 'def', page_2.last_version.message
|
||||
assert_not_equal page_1.version.sha, page_2.version.sha
|
||||
refute_equal page_1.version.sha, page_2.version.sha
|
||||
end
|
||||
|
||||
test "creates page" do
|
||||
@@ -320,7 +320,7 @@ EOF
|
||||
name = "#{dir}/bar"
|
||||
get "/gollum/create/#{name}"
|
||||
assert_match(/\/#{dir}/, last_response.body)
|
||||
assert_no_match(/[^\/]#{dir}/, last_response.body)
|
||||
refute_match(/[^\/]#{dir}/, last_response.body)
|
||||
end
|
||||
|
||||
test "create with template succeed if template exists" do
|
||||
@@ -344,6 +344,45 @@ EOF
|
||||
Precious::App.set(:wiki_options, { :template_page => false })
|
||||
end
|
||||
|
||||
test "create with template filter without parameter" do
|
||||
Precious::App.set(:wiki_options, { :template_page => true })
|
||||
|
||||
# arrange
|
||||
now = Time.parse('2022-04-16')
|
||||
Gollum::TemplateFilter.add_filter("{{today}}", & -> () { now.strftime("%Y-%m-%d") })
|
||||
template_content = "# Daily Log, {{today}}"
|
||||
|
||||
@wiki.write_page("daily-logs/_Template",
|
||||
:markdown,
|
||||
template_content)
|
||||
# act
|
||||
get "/gollum/create/daily-logs/test"
|
||||
# assert
|
||||
assert last_response.ok?
|
||||
assert_match("# Daily Log, 2022-04-16", last_response.body)
|
||||
|
||||
Precious::App.set(:wiki_options, { :template_page => false })
|
||||
end
|
||||
|
||||
test "create with template filter with parameter" do
|
||||
Precious::App.set(:wiki_options, { :template_page => true })
|
||||
|
||||
# arrange
|
||||
Gollum::TemplateFilter.add_filter("{{page_name}}", & -> (page) { page.name })
|
||||
template_content = "# Daily Log, {{page_name}}"
|
||||
|
||||
@wiki.write_page("daily-logs/_Template",
|
||||
:markdown,
|
||||
template_content)
|
||||
# act
|
||||
get "/gollum/create/daily-logs/2022-04-16"
|
||||
# assert
|
||||
assert last_response.ok?
|
||||
assert_match("# Daily Log, 2022-04-16", last_response.body)
|
||||
|
||||
Precious::App.set(:wiki_options, { :template_page => false })
|
||||
end
|
||||
|
||||
test "edit returns nil for non-existant page" do
|
||||
# post '/edit' fails. post '/edit/' works.
|
||||
page = 'not-real-page'
|
||||
@@ -351,7 +390,7 @@ EOF
|
||||
post '/gollum/edit/', :content => 'edit_msg',
|
||||
:page => page, :path => path, :message => ''
|
||||
page_e = @wiki.page(::File.join(path,page))
|
||||
assert_equal nil, page_e
|
||||
assert_nil page_e
|
||||
end
|
||||
|
||||
test "edit allows changing format" do
|
||||
@@ -407,13 +446,21 @@ EOF
|
||||
|
||||
@wiki.clear_cache
|
||||
page = @wiki.page(name)
|
||||
assert_not_equal 'abc', page.raw_data
|
||||
refute_equal 'abc', page.raw_data
|
||||
end
|
||||
|
||||
test "uploading is not allowed unless explicitly enabled" do
|
||||
temp_upload_file = Tempfile.new(['upload', '.file']) << 'abc'
|
||||
temp_upload_file.close
|
||||
post "/gollum/upload_file", :file => Rack::Test::UploadedFile.new(::File.open(temp_upload_file))
|
||||
|
||||
Precious::App.set(
|
||||
:wiki_options,
|
||||
{allow_uploads: false, per_page_uploads: false}
|
||||
)
|
||||
|
||||
post '/gollum/upload_file',
|
||||
file: Rack::Test::UploadedFile.new(File.open(temp_upload_file))
|
||||
|
||||
assert_equal 405, last_response.status
|
||||
end
|
||||
|
||||
@@ -483,7 +530,7 @@ EOF
|
||||
|
||||
@wiki.clear_cache
|
||||
page = @wiki.page(name)
|
||||
assert_equal nil, page
|
||||
assert_nil page
|
||||
end
|
||||
|
||||
test "previews content" do
|
||||
@@ -507,7 +554,7 @@ EOF
|
||||
|
||||
@wiki.clear_cache
|
||||
page2 = @wiki.page('B')
|
||||
assert_not_equal page1.version.sha, page2.version.sha
|
||||
refute_equal page1.version.sha, page2.version.sha
|
||||
assert_equal "INITIAL", page2.raw_data.strip
|
||||
assert_equal "Revert commit 7c45b5f", page2.version.message
|
||||
end
|
||||
@@ -521,7 +568,7 @@ EOF
|
||||
|
||||
@wiki.clear_cache
|
||||
page2 = @wiki.page('A')
|
||||
assert_not_equal page1.version.sha, page2.version.sha
|
||||
refute_equal page1.version.sha, page2.version.sha
|
||||
assert_equal "INITIAL", page2.raw_data.strip
|
||||
end
|
||||
|
||||
@@ -583,7 +630,7 @@ EOF
|
||||
{ :name => 'user1', :email => 'user1' });
|
||||
|
||||
get page
|
||||
assert_no_match /custom.js/, last_response.body
|
||||
refute_match /custom.js/, last_response.body
|
||||
end
|
||||
|
||||
test "add custom.js if setting" do
|
||||
@@ -652,7 +699,7 @@ EOF
|
||||
get "A"
|
||||
|
||||
assert last_response.ok?
|
||||
assert_no_match /meta name="robots" content="noindex, nofollow"/, last_response.body
|
||||
refute_match /meta name="robots" content="noindex, nofollow"/, last_response.body
|
||||
|
||||
get "A/fc66539528eb96f21b2bbdbf557788fe8a1196ac"
|
||||
|
||||
@@ -668,6 +715,13 @@ EOF
|
||||
assert_equal last_response.status, 302
|
||||
end
|
||||
|
||||
test "view deleted page in history" do
|
||||
get 'C/db8b297cf5a31b46ac24500edfdbd0d3d8eed4eb'
|
||||
|
||||
assert last_response.ok?
|
||||
assert_match /This page will be deleted in the next commit :\(/, last_response.body
|
||||
end
|
||||
|
||||
def app
|
||||
Precious::App
|
||||
end
|
||||
@@ -817,7 +871,7 @@ context "Frontend with lotr" do
|
||||
assert last_response.ok?
|
||||
assert_equal last_response.body.include?('delete-link'), false
|
||||
assert_equal last_response.body.include?('page-info-toggle'), false
|
||||
assert last_response.body.include?('This version of the page was edited by <b>Tom Preston-Werner</b> at 2010-04-07')
|
||||
assert_match %r{This version of the page was edited by <b>Tom Preston-Werner</b> at <time datetime="2010-04-07T19:49:43Z" data-format="%Y-%m-%d %H:%M:%S">\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}</time>.}, last_response.body
|
||||
assert last_response.body.include?("<a href=\"/Bilbo-Baggins.md\">View the most recent version.</a></p>")
|
||||
end
|
||||
|
||||
@@ -827,7 +881,7 @@ context "Frontend with lotr" do
|
||||
|
||||
get "Data.csv/#{old_sha}"
|
||||
assert last_response.ok?
|
||||
assert_no_match /Samwise,Gamgee/, last_response.body
|
||||
refute_match /Samwise,Gamgee/, last_response.body
|
||||
|
||||
get "Data.csv/#{update_sha}"
|
||||
assert last_response.ok?
|
||||
@@ -872,7 +926,7 @@ context "Frontend with page-file-dir" do
|
||||
name = "#{dir}/baz"
|
||||
get "/gollum/create/#{name}"
|
||||
assert_match(/\/#{dir}/, last_response.body)
|
||||
assert_no_match(/[^\/]#{dir}/, last_response.body)
|
||||
refute_match(/[^\/]#{dir}/, last_response.body)
|
||||
end
|
||||
|
||||
test "use custom.css from page-file-dir path if page-file-dir is set" do
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# ~*~ encoding: utf-8 ~*~
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||
require 'nokogiri'
|
||||
require 'json'
|
||||
require 'time'
|
||||
|
||||
def local_time
|
||||
Precious::App.set(:wiki_options, { show_local_time: true})
|
||||
end
|
||||
|
||||
def no_local_time
|
||||
Precious::App.set(:wiki_options, { show_local_time: false})
|
||||
end
|
||||
|
||||
def assert_time_tags(body)
|
||||
tags = Nokogiri::HTML(body).css('time')
|
||||
assert_equal tags.empty?, false
|
||||
tags.each do |tag|
|
||||
assert Time.parse(tag[:datetime]).utc?
|
||||
end
|
||||
end
|
||||
|
||||
context ":show_local_time option" do
|
||||
include Rack::Test::Methods
|
||||
|
||||
setup do
|
||||
@path = cloned_testpath('examples/lotr.git')
|
||||
@wiki = Gollum::Wiki.new(@path)
|
||||
Precious::App.set(:gollum_path, @path)
|
||||
local_time()
|
||||
end
|
||||
|
||||
teardown do
|
||||
FileUtils.rm_rf(@path)
|
||||
end
|
||||
|
||||
test "last_commit_info no local time" do
|
||||
no_local_time()
|
||||
get '/gollum/last_commit_info', {path: 'Home.textile'}
|
||||
assert_equal Time.parse(JSON.parse(last_response.body)['date']).utc?, false
|
||||
end
|
||||
|
||||
test "last_commit_info local time" do
|
||||
local_time()
|
||||
get '/gollum/last_commit_info', {path: 'Home.textile'}
|
||||
assert Time.parse(JSON.parse(last_response.body)['date']).utc?
|
||||
end
|
||||
|
||||
test "datetime attributes in utc" do
|
||||
get '/Home/b0d108328459e44fff4a76cd19b10ddc34adce4b'
|
||||
assert_time_tags last_response.body
|
||||
|
||||
get '/gollum/latest_changes'
|
||||
assert_time_tags last_response.body
|
||||
|
||||
get '/gollum/history/Home'
|
||||
assert_time_tags last_response.body
|
||||
|
||||
get '/gollum/commit/b0d108328459e44fff4a76cd19b10ddc34adce4b'
|
||||
assert_time_tags last_response.body
|
||||
end
|
||||
|
||||
def app
|
||||
Precious::App
|
||||
end
|
||||
end
|
||||
+59
-61
@@ -1,28 +1,6 @@
|
||||
# ~*~ encoding: utf-8 ~*~
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||
|
||||
# Original contents of Subdir/Foo.md:
|
||||
# waa
|
||||
# [[Samwi]]
|
||||
# [[samwise gamgee.mediaWiki]]
|
||||
# [[Samwise Gamgee.mediawiki]]
|
||||
# [[Samwise Gamgee]]
|
||||
# [[Test|Samwise Gamgee#Anchor]]
|
||||
# [[Waaa|Test]]
|
||||
# [[Zaa]]
|
||||
|
||||
# Contents of Subdir/Foo.md after successful tag migration
|
||||
result = <<EOF
|
||||
waa
|
||||
[[Samwi]]
|
||||
[[/Samwise Gamgee.mediawiki]]
|
||||
[[/Samwise Gamgee.mediawiki]]
|
||||
[[/Samwise Gamgee.md]]
|
||||
[[Test|/Samwise Gamgee.md#Anchor]]
|
||||
[[Waaa|/Bar/Test.md]]
|
||||
[[Subsub/Zaa.md]]
|
||||
EOF
|
||||
|
||||
def load_script(**args)
|
||||
settings = {
|
||||
:run_silent => true,
|
||||
@@ -32,9 +10,12 @@ def load_script(**args)
|
||||
:page_file_dir => nil,
|
||||
}.merge(args)
|
||||
|
||||
settings.each do |const, val|
|
||||
const_name = const.to_s.upcase
|
||||
Object.const_set(const_name, val) unless Object.const_defined?(const_name) && Object.const_get(const_name) == val
|
||||
settings.each do |setting, val|
|
||||
variable_name = :"@@#{setting.to_s}"
|
||||
|
||||
unless Object.class_variable_defined?(variable_name) && Object.class_variable_get(variable_name) == val
|
||||
Object.class_variable_set(variable_name, val)
|
||||
end
|
||||
end
|
||||
|
||||
script_path = File.expand_path(File.join(File.dirname(__FILE__), '../', 'bin', 'gollum-migrate-tags'))
|
||||
@@ -44,43 +25,60 @@ def load_script(**args)
|
||||
end
|
||||
end
|
||||
|
||||
unless ENV['CI']
|
||||
context '4.x -> 5.x tag migrator' do
|
||||
include Rack::Test::Methods
|
||||
|
||||
context '4.x -> 5.x tag migrator' do
|
||||
include Rack::Test::Methods
|
||||
|
||||
setup do
|
||||
@path = cloned_testpath("examples/lotr_migration.git")
|
||||
end
|
||||
|
||||
test 'repair broken links' do
|
||||
load_script
|
||||
|
||||
f = ::File.new(::File.join(@path, 'Subdir/Foo.md'), 'r')
|
||||
assert_equal result, f.read
|
||||
end
|
||||
|
||||
test 'change spaced filenames to hyphenated filenames' do
|
||||
load_script(hyphenate: true)
|
||||
|
||||
f = ::File.new(::File.join(@path, 'Home.textile'), 'r')
|
||||
output = f.read
|
||||
assert_equal true, output.include?('[[Bilbo-Baggins.md]]')
|
||||
assert_equal true, output.include?('[[evil|Mordor/Eye-Of-Sauron.md]]')
|
||||
end
|
||||
|
||||
test 'migration with page file dir' do
|
||||
load_script(page_file_dir: 'Subdir')
|
||||
|
||||
f = ::File.new(::File.join(@path, 'Subdir/Foo.md'), 'r')
|
||||
output = f.read
|
||||
assert_equal true, output.include?('[[Subsub/Zaa.md]]')
|
||||
assert_equal true, output.include?('[[Samwi]]')
|
||||
end
|
||||
|
||||
teardown do
|
||||
FileUtils.rm_rf(@path)
|
||||
end
|
||||
setup do
|
||||
@path = cloned_testpath("examples/lotr_migration.git")
|
||||
end
|
||||
|
||||
test 'repair broken links' do
|
||||
# The original contents of Subdir/Foo.md:
|
||||
#
|
||||
# waa
|
||||
# [[Samwi]]
|
||||
# [[samwise gamgee.mediaWiki]]
|
||||
# [[Samwise Gamgee.mediawiki]]
|
||||
# [[Samwise Gamgee]]
|
||||
# [[Test|Samwise Gamgee#Anchor]]
|
||||
# [[Waaa|Test]]
|
||||
# [[Zaa]]
|
||||
#
|
||||
# The contents will be updated after running the migration script.
|
||||
load_script
|
||||
|
||||
file = ::File.new(::File.join(@path, 'Subdir/Foo.md'), 'r')
|
||||
assert_equal <<~FILE_CONTENTS, file.read
|
||||
waa
|
||||
[[Samwi]]
|
||||
[[/Samwise Gamgee.mediawiki]]
|
||||
[[/Samwise Gamgee.mediawiki]]
|
||||
[[/Samwise Gamgee.md]]
|
||||
[[Test|/Samwise Gamgee.md#Anchor]]
|
||||
[[Waaa|/Bar/Test.md]]
|
||||
[[Subsub/Zaa.md]]
|
||||
FILE_CONTENTS
|
||||
end
|
||||
|
||||
test 'change spaced filenames to hyphenated filenames' do
|
||||
load_script(hyphenate: true)
|
||||
|
||||
f = ::File.new(::File.join(@path, 'Home.textile'), 'r')
|
||||
output = f.read
|
||||
assert_equal true, output.include?('[[Bilbo-Baggins.md]]')
|
||||
assert_equal true, output.include?('[[evil|Mordor/Eye-Of-Sauron.md]]')
|
||||
end
|
||||
|
||||
test 'migration with page file dir' do
|
||||
load_script(page_file_dir: 'Subdir')
|
||||
|
||||
f = ::File.new(::File.join(@path, 'Subdir/Foo.md'), 'r')
|
||||
output = f.read
|
||||
assert_equal true, output.include?('[[Subsub/Zaa.md]]')
|
||||
assert_equal true, output.include?('[[Samwi]]')
|
||||
end
|
||||
|
||||
teardown do
|
||||
FileUtils.rm_rf(@path)
|
||||
end
|
||||
end
|
||||
@@ -35,7 +35,7 @@ context "Precious::Views::Page" do
|
||||
@view.instance_variable_set :@content, page.formatted_data
|
||||
@view.instance_variable_set :@h1_title, false
|
||||
|
||||
assert_include @view.breadcrumb, "数学 📘"
|
||||
assert_includes @view.breadcrumb, "数学 📘"
|
||||
end
|
||||
|
||||
test 'page <title> is the page header from content, if present' do
|
||||
|
||||
@@ -1,43 +1,59 @@
|
||||
# ~*~ encoding: utf-8 ~*~
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||
|
||||
class TestTemplateCascade < Minitest::Unit::TestCase
|
||||
context "Precious::Views::TemplateCascade" do
|
||||
include Rack::Test::Methods
|
||||
|
||||
def setup
|
||||
setup do
|
||||
@path = cloned_testpath('examples/lotr.git')
|
||||
Precious::App.set(:gollum_path, @path)
|
||||
Precious::App.set(:wiki_options, {template_dir: testpath('examples/template_cascade')})
|
||||
Precious::App.set(
|
||||
:wiki_options,
|
||||
{template_dir: testpath('examples/template_cascade')}
|
||||
)
|
||||
@wiki = Gollum::Wiki.new(@path)
|
||||
end
|
||||
|
||||
def teardown
|
||||
teardown do
|
||||
FileUtils.rm_rf(@path)
|
||||
|
||||
Precious::App.set(:wiki_options, {template_dir: nil})
|
||||
|
||||
# The following line has been added to avoid order-dependent test failures.
|
||||
# We saw issues where the class variable `@@template_priority_path` was not
|
||||
# being reset between test cases.
|
||||
Precious::Views::TemplateCascade.class_variable_set(
|
||||
:@@template_priority_path,
|
||||
nil
|
||||
)
|
||||
end
|
||||
|
||||
def app
|
||||
Precious::App
|
||||
Precious::App.new
|
||||
end
|
||||
|
||||
def test_overridden_page_template_is_used
|
||||
test "overridden_page_template_is_used" do
|
||||
get '/Home'
|
||||
|
||||
assert last_response.body.include?('PAGE_OVERRIDE')
|
||||
end
|
||||
|
||||
def test_overridden_navbar_partial_is_used
|
||||
test "test_overridden_navbar_partial_is_used" do
|
||||
get '/Home'
|
||||
|
||||
assert last_response.body.include?('NAVBAR_OVERRIDE')
|
||||
end
|
||||
|
||||
def test_overridden_templates_are_ignore_without_template_dir_set
|
||||
test "test_overridden_templates_are_ignore_without_template_dir_set" do
|
||||
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
|
||||
|
||||
refute_match /PAGE_OVERRIDE/, last_response.body
|
||||
refute_match /NAVBAR_OVERRIDE/, last_response.body
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user